diff --git a/13_composite/README.md b/13_composite/README.md new file mode 100644 index 0000000..ebcb15c --- /dev/null +++ b/13_composite/README.md @@ -0,0 +1,5 @@ +# 组合模式 + +组合模式统一对象和对象集,使得使用相同接口使用对象和对象集。 + +组合模式常用于树状结构,用于统一叶子节点和树节点的访问,并且可以用于应用某一操作到所有子节点。 diff --git a/13_composite/composite.go b/13_composite/composite.go new file mode 100644 index 0000000..0e3e87c --- /dev/null +++ b/13_composite/composite.go @@ -0,0 +1,91 @@ +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) + } +} diff --git a/13_composite/composite_test.go b/13_composite/composite_test.go new file mode 100644 index 0000000..f1d207f --- /dev/null +++ b/13_composite/composite_test.go @@ -0,0 +1,29 @@ +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 +}