From 2a5633614cb5cf286a77b3e39db3902297b44578 Mon Sep 17 00:00:00 2001 From: Edward Date: Sat, 2 May 2020 17:14:20 +0800 Subject: [PATCH] finish composite pattern --- structure/13_composite/composite.go | 107 +++++++++++++++++++---- structure/13_composite/composite_test.go | 55 +++++++++++- structure/README.md | 7 +- 3 files changed, 150 insertions(+), 19 deletions(-) diff --git a/structure/13_composite/composite.go b/structure/13_composite/composite.go index abde553..f86177e 100644 --- a/structure/13_composite/composite.go +++ b/structure/13_composite/composite.go @@ -1,26 +1,101 @@ package composite -//ItemType 具体物品的类型 -type ItemType int - -//定义两种数据类型,叶子和复合节点 -const ( - ManCloth ItemType = iota - WomanCloth - HatOrShose +import ( + "fmt" + "reflect" ) -//IWearingItem 定义复合类型的接口,表示穿戴物品 -type IWearingItem interface { - GetWearingType() ItemType +//////////////////////////////// +//使用集装箱与货物的例子 +//////////////////////////////// + +//IShippedCargo 定义基本的对外一致性访问 +type IShippedCargo interface { + GetCargoType() string + ShowContent() } -//CompositedComponet 复合类型,复合类型知道所有的具体类型 -type CompositedComponet struct { +//IBox 复合类型的接口 +type IBox interface { + IShippedCargo //继承接口 + PutInCargo(cargo IShippedCargo) //放入一个子类型 + GetChildren() []IBox } -//NewComponent return a concrate -func NewComponent(kind int, name string) IWearingItem { +//////////////////////////////// +//下面三个是对象的该模式的关键结构 +//////////////////////////////// + +//Cargo class 基本的货物类型可以被继承 +type Cargo struct { + Volume uint //货物需要要尺寸 + Description string //描述 +} + +//GetCargoType return type +func (c *Cargo) GetCargoType() string { + return reflect.TypeOf(c).String() +} + +//ShowContent return type +func (c *Cargo) ShowContent() { + typeName := reflect.TypeOf(c).String() + fmt.Println("Type: ", typeName, " Content ", c.Description) + +} + +//Box 复合类型,表示集装箱 +//Box 复合类型,集装箱里面装具体的货物,也可以继续放箱子 +type Box struct { + Cargo //继承货物类 + InnerSpace uint //内部空间 + Children []IShippedCargo //有子对象 +} + +//PutInCargo 增加新的能力 +//PutInCargo (cargo ICargo) //放入一个子类型 +func (b *Box) PutInCargo(cargo IShippedCargo) { + fmt.Println("get a Child: ", cargo.GetCargoType()) + + b.Children = append(b.Children, cargo) + +} + +//GetChildren () []ICompositedCargo +func (b *Box) GetChildren() []IShippedCargo { + return b.Children +} + +//ShowContent 覆盖继承实现 +//ShowContent display children content +func (b *Box) ShowContent() { + typeName := reflect.TypeOf(b).String() + fmt.Println("Type: ", typeName, " InnerSpace ", b.InnerSpace, " Children: ", b.Description) + count := len(b.Children) + fmt.Println("Children Count: ", count, " Description ", b.Description) + for _, child := range b.Children { + //判断类型 + switch child.(type) { + case *Box: + fmt.Println("Current Child is a Box: Type cast to (*Box) ") + child.(*Box).ShowContent() + case *SingleCargo: + fmt.Println("Current Child is a Single Cargo: Type cast to (*SingleCargo) ") + child.(*SingleCargo).ShowContent() + } + } + +} + +//SingleCargo 具体的非复合类型,对应多叉树的叶子节点 +type SingleCargo struct { + Cargo //继承货物类,具有基本的货物熟悉 + From, To string //货是从谁发到谁的 +} + +//ShowContent return type +func (s *SingleCargo) ShowContent() { + typeName := reflect.TypeOf(s).String() + fmt.Println("Type: ", typeName, " From ", s.From, " To ", s.To, " Content ", s.Description) - return nil } diff --git a/structure/13_composite/composite_test.go b/structure/13_composite/composite_test.go index 143a6bf..2beeaab 100644 --- a/structure/13_composite/composite_test.go +++ b/structure/13_composite/composite_test.go @@ -2,6 +2,59 @@ package composite import "testing" -func TestComposite(t *testing.T) { +//我们目的是:使用一致性的方式访问一类具有共性并相互组合起来的对象 + +func TestCompositeconnections(t *testing.T) { + + box1 := &Box{Cargo: Cargo{1, "Big Box"}, InnerSpace: 130000} + + box2 := &Box{Cargo{2, "Middle Box"}, 80000, nil} + + box1.PutInCargo(box2) + + cargo1 := &SingleCargo{Cargo{3, "Hat"}, "CN", "CA"} + + box1.PutInCargo(cargo1) + + cargo2 := &SingleCargo{Cargo: Cargo{4, "Men Cloth"}, From: "China", To: "UK"} + + cargo3 := &SingleCargo{Cargo: Cargo{5, "Women Cloth"}, From: "HK", To: "TW"} + + box2.PutInCargo(cargo2) + + box2.PutInCargo(cargo3) + + box1.ShowContent() + + //Box1 + // -Box2 + // -Cargo 2 + // -Cargo 3 + // -Cargo1 } + +func TestComposite(t *testing.T) { + + box1 := Box{Cargo: Cargo{1, "Big Box"}, InnerSpace: 130000} + box1.ShowContent() + + box2 := Box{Cargo{2, "Middle Box"}, 80000, nil} + + box2.ShowContent() + + cargo1 := SingleCargo{Cargo{1, "Hat"}, "CN", "CA"} + + cargo1.ShowContent() + + cargo2 := SingleCargo{Cargo: Cargo{2, "Men Cloth"}, From: "China", To: "UK"} + + cargo2.ShowContent() + + cargo3 := &SingleCargo{Cargo: Cargo{2, "Women Cloth"}, From: "HK", To: "TW"} + + cargo3.ShowContent() + + //Call base class + cargo3.Cargo.ShowContent() +} diff --git a/structure/README.md b/structure/README.md index 5855e92..20d3f18 100644 --- a/structure/README.md +++ b/structure/README.md @@ -1,7 +1,10 @@ # structure pattern -结构模式,就是多种对象之间的相互搭配构成一个新的结构形态. +结构模式,就是多种对象之间的相互搭配/连接构成一个新的结构形态,从而满足一定目的,比如方便访问,扩展功能,对象复用,功能转换适配等 建筑结构是一个很生动鲜明的结构模式代表,同样是钢筋、混凝土,建筑的不同结构,标示着这些建筑的不同作用,做成桥的结构,就是支持行人过路的,做成房子就是住人的, 最好脑子里面形成不同建筑结构的画面,这个是最容易跟结构产生联系的一个形态对象,也是对结构模式的最佳描述之一。 -所以,代码也一样,不同的对象构成的不同形态,就意味着这些对象是有不同的目的设计, +所以,代码也一样,不同的对象构成的不同形态,就意味着这些对象是有不同的目的设计. + + +