mirror of
https://github.com/crazybber/go-pattern-examples.git
synced 2024-11-25 13:16:02 +03:00
add composite mod codes
This commit is contained in:
parent
82d8c7cf02
commit
5fbbfbcb98
24
README.md
24
README.md
@ -24,24 +24,24 @@ Go常用的、面向工程化和最佳实践的模式套路,包含常见的23
|
|||||||
+ [x] [外观模式(Facade)](./structure/01_facade)
|
+ [x] [外观模式(Facade)](./structure/01_facade)
|
||||||
+ [x] [适配器模式(Adapter)](./structure/02_adapter)
|
+ [x] [适配器模式(Adapter)](./structure/02_adapter)
|
||||||
+ [x] [代理模式(Proxy)](./structure/09_proxy)
|
+ [x] [代理模式(Proxy)](./structure/09_proxy)
|
||||||
+ [组合模式(Composite)](./structure/13_composite)
|
+ [ ] [复合模式(Composite)](./structure/13_composite)
|
||||||
+ [享元模式(Flyweight)](./structure/18_flyweight)
|
+ [x] [享元模式(Flyweight)](./structure/18_flyweight)
|
||||||
+ [装饰模式(Decorator)](./structure/20_decorator)
|
+ [ ] [装饰模式(Decorator)](./structure/20_decorator)
|
||||||
+ [x] [桥模式(Bridge)](./structure/22_bridge)
|
+ [x] [桥模式(Bridge)](./structure/22_bridge)
|
||||||
|
|
||||||
## 行为型模式
|
## 行为型模式
|
||||||
|
|
||||||
+ [x] [中介者模式(Mediator)](./behavior/08_mediator)
|
+ [x] [中介者模式(Mediator)](./behavior/08_mediator)
|
||||||
+ [观察者模式(Observer)](./behavior/10_observer)
|
+ [ ] [观察者模式(Observer)](./behavior/10_observer)
|
||||||
+ [命令模式(Command)](./behavior/11_command)
|
+ [ ] [命令模式(Command)](./behavior/11_command)
|
||||||
+ [迭代器模式(Iterator)](./behavior/12_iterator)
|
+ [ ] [迭代器模式(Iterator)](./behavior/12_iterator)
|
||||||
+ [模板方法模式(Template Method)](./behavior/14_template_method)
|
+ [ ] [模板方法模式(Template Method)](./behavior/14_template_method)
|
||||||
+ [x] [策略模式(Strategy)](./behavior/15_strategy)
|
+ [x] [策略模式(Strategy)](./behavior/15_strategy)
|
||||||
+ [状态模式(State)](./behavior/behavior16_state)
|
+ [ ] [状态模式(State)](./behavior/behavior16_state)
|
||||||
+ [备忘录模式(Memento)](./behavior/17_memento)
|
+ [ ] [备忘录模式(Memento)](./behavior/17_memento)
|
||||||
+ [解释器模式(Interpreter)](./behavior/19_interpreter)
|
+ [ ] [解释器模式(Interpreter)](./behavior/19_interpreter)
|
||||||
+ [职责链模式(Chain of Responsibility)](./behavior/21_chain_of_responsibility)
|
+ [ ] [职责链模式(Chain of Responsibility)](./behavior/21_chain_of_responsibility)
|
||||||
+ [访问者模式(Visitor)](./behavior/23_visitor)
|
+ [ ] [访问者模式(Visitor)](./behavior/23_visitor)
|
||||||
+ [x] [闭包选项模式(Function Option)](./behavior/26_option)
|
+ [x] [闭包选项模式(Function Option)](./behavior/26_option)
|
||||||
|
|
||||||
## Go More
|
## Go More
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
# 组合模式
|
|
||||||
|
|
||||||
这里说到的组合模式不同于go本身的组合设计理念,go本身的组合宽泛的多,用于结构于结构、结构于接口、接口与接口的组合.
|
|
||||||
|
|
||||||
这里说的组合模式是为统一对象和对象集,使得外部可以使用相同接口使用对象和对象集。
|
|
||||||
|
|
||||||
组合模式常用于树状结构,用于统一叶子节点和树节点的访问,并且可以用于应用某一操作到所有子节点。
|
|
@ -1,91 +0,0 @@
|
|||||||
package composite
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
type Component interface {
|
|
||||||
Parent() Component
|
|
||||||
SetParent(Component)
|
|
||||||
Name() string
|
|
||||||
SetName(string)
|
|
||||||
AddChild(Component)
|
|
||||||
Print(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
LeafNode = iota
|
|
||||||
CompositeNode
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewComponent(kind int, name string) Component {
|
|
||||||
var c Component
|
|
||||||
switch kind {
|
|
||||||
case LeafNode:
|
|
||||||
c = NewLeaf()
|
|
||||||
case CompositeNode:
|
|
||||||
c = NewComposite()
|
|
||||||
}
|
|
||||||
|
|
||||||
c.SetName(name)
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
type component struct {
|
|
||||||
parent Component
|
|
||||||
name string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *component) Parent() Component {
|
|
||||||
return c.parent
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *component) SetParent(parent Component) {
|
|
||||||
c.parent = parent
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *component) Name() string {
|
|
||||||
return c.name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *component) SetName(name string) {
|
|
||||||
c.name = name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *component) AddChild(Component) {}
|
|
||||||
|
|
||||||
func (c *component) Print(string) {}
|
|
||||||
|
|
||||||
type Leaf struct {
|
|
||||||
component
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLeaf() *Leaf {
|
|
||||||
return &Leaf{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Leaf) Print(pre string) {
|
|
||||||
fmt.Printf("%s-%s\n", pre, c.Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
type Composite struct {
|
|
||||||
component
|
|
||||||
childs []Component
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewComposite() *Composite {
|
|
||||||
return &Composite{
|
|
||||||
childs: make([]Component, 0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Composite) AddChild(child Component) {
|
|
||||||
child.SetParent(c)
|
|
||||||
c.childs = append(c.childs, child)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Composite) Print(pre string) {
|
|
||||||
fmt.Printf("%s+%s\n", pre, c.Name())
|
|
||||||
pre += " "
|
|
||||||
for _, comp := range c.childs {
|
|
||||||
comp.Print(pre)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package composite
|
|
||||||
|
|
||||||
func ExampleComposite() {
|
|
||||||
root := NewComponent(CompositeNode, "root")
|
|
||||||
c1 := NewComponent(CompositeNode, "c1")
|
|
||||||
c2 := NewComponent(CompositeNode, "c2")
|
|
||||||
c3 := NewComponent(CompositeNode, "c3")
|
|
||||||
|
|
||||||
l1 := NewComponent(LeafNode, "l1")
|
|
||||||
l2 := NewComponent(LeafNode, "l2")
|
|
||||||
l3 := NewComponent(LeafNode, "l3")
|
|
||||||
|
|
||||||
root.AddChild(c1)
|
|
||||||
root.AddChild(c2)
|
|
||||||
c1.AddChild(c3)
|
|
||||||
c1.AddChild(l1)
|
|
||||||
c2.AddChild(l2)
|
|
||||||
c2.AddChild(l3)
|
|
||||||
|
|
||||||
root.Print("")
|
|
||||||
// Output:
|
|
||||||
// +root
|
|
||||||
// +c1
|
|
||||||
// +c3
|
|
||||||
// -l1
|
|
||||||
// +c2
|
|
||||||
// -l2
|
|
||||||
// -l3
|
|
||||||
}
|
|
BIN
images/composite.png
Normal file
BIN
images/composite.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.4 KiB |
25
structure/13_composite/README.md
Normal file
25
structure/13_composite/README.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# 复合模式
|
||||||
|
|
||||||
|
复合模式,目的是为了实现对一类对象的一致性访问,复合模式也叫组合模式,但是不同于go本身的组合设计理念,go本身的组合宽泛的多,用于结构与结构、结构与接口、接口与接口的嵌套组合.
|
||||||
|
|
||||||
|
我认为用复合表述更准确一些,复合模式的要点在于设计复合类型,兼容多种有相关关系类型,使得外部可以使用的使用方式使用相同接口(往往可能需要传入不同的参数)访问对象或者对象集。
|
||||||
|
|
||||||
|
复合模式在内存中的数据结构逻辑上常常表达为一个树结构,用于统一叶子节点对象和非叶子节点对象的访问,很明显复合模式可用于与类别相关的问题处理,并且尤其擅长类别相似的问题的处理。
|
||||||
|
|
||||||
|
所以反过来想,当遇到分类相关并且关系可以表达为<整体-局部>关系的,或者遇到可以用树状逻辑梳理和表达的问题时候,复合模式可能就是最佳的问题解决思路了
|
||||||
|
|
||||||
|
引申一下,在我们处理算法的时候,往往是一个输入一个输出,但是在处理过程中往往是要将问题进行分类,所以复合模式思想也可强化算法思路.
|
||||||
|
|
||||||
|
符合模式中的核心重点是一个 :复合对象,这个复合对象,能同时代表叶子节点和非叶子节点的对接。
|
||||||
|
|
||||||
|
|
||||||
|
现实生活中服务装供应商库存盘点中的衣物分类就是一个很好的例子,
|
||||||
|
|
||||||
|
- 服装
|
||||||
|
- 男装
|
||||||
|
- 女装
|
||||||
|
- 上套裙
|
||||||
|
- 短吊带
|
||||||
|
- 鞋帽 --->f鞋帽,从最基础通用性上来讲,不分男女
|
||||||
|
|
||||||
|
![一个示例](../../images/Composite.png)
|
26
structure/13_composite/composite.go
Normal file
26
structure/13_composite/composite.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package composite
|
||||||
|
|
||||||
|
//ItemType 具体物品的类型
|
||||||
|
type ItemType int
|
||||||
|
|
||||||
|
//定义两种数据类型,叶子和复合节点
|
||||||
|
const (
|
||||||
|
ManCloth ItemType = iota
|
||||||
|
WomanCloth
|
||||||
|
HatOrShose
|
||||||
|
)
|
||||||
|
|
||||||
|
//IWearingItem 定义复合类型的接口,表示穿戴物品
|
||||||
|
type IWearingItem interface {
|
||||||
|
GetWearingType() ItemType
|
||||||
|
}
|
||||||
|
|
||||||
|
//CompositedComponet 复合类型,复合类型知道所有的具体类型
|
||||||
|
type CompositedComponet struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
//NewComponent return a concrate
|
||||||
|
func NewComponent(kind int, name string) IWearingItem {
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
7
structure/13_composite/composite_test.go
Normal file
7
structure/13_composite/composite_test.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package composite
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestComposite(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
@ -3,7 +3,7 @@
|
|||||||
* @Author: Edward
|
* @Author: Edward
|
||||||
* @Date: 2020-05-01 17:24:28
|
* @Date: 2020-05-01 17:24:28
|
||||||
* @Last Modified by: Edward
|
* @Last Modified by: Edward
|
||||||
* @Last Modified time: 2020-05-01 19:45:32
|
* @Last Modified time: 2020-05-01 19:46:30
|
||||||
*/
|
*/
|
||||||
package flyweight
|
package flyweight
|
||||||
|
|
||||||
@ -24,6 +24,7 @@ func TestDeliveryPackets(t *testing.T) {
|
|||||||
|
|
||||||
deliver2 := dc.GetDeliver("lily")
|
deliver2 := dc.GetDeliver("lily")
|
||||||
|
|
||||||
|
//一次送货任务
|
||||||
dc.DeliverTask("lily", []string{"box1", "box2"})
|
dc.DeliverTask("lily", []string{"box1", "box2"})
|
||||||
|
|
||||||
dc.DeliverTask("lily", []string{"box6", "box7", "box8"})
|
dc.DeliverTask("lily", []string{"box6", "box7", "box8"})
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
# 装饰模式
|
# 装饰模式
|
||||||
|
|
||||||
装饰模式使用对象组合的方式动态改变或增加对象行为。
|
装饰模式就是比较简单了,就是在不改变原有对象和类型的情况下,对其进行装饰,扩展,以达到公共强化和扩展的目的。
|
||||||
|
|
||||||
Go语言借助于匿名组合和非入侵式接口可以很方便实现装饰模式。
|
Go语言借助于匿名组合和非入侵式接口可以很方便实现装饰模式。使用匿名组合,在装饰器中不必显式定义转调原对象方法。
|
||||||
|
|
||||||
使用匿名组合,在装饰器中不必显式定义转调原对象方法。
|
|
||||||
|
Loading…
Reference in New Issue
Block a user