大B:“下面是组合模式的结构图如图5-1所示。”
图5-1 结构图
大B:“组合模式为组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理组合模式的子部件。”
abstract class Component { protected string name; public Component(string name) { this.name=name; } public abstract void Add(component c);//通常都用Add和Remove方法来提供增加或移出树叶或树枝的功能 public abstract void Remove(Component c); public abstract void Display(in depth); }
Leaf在组合中表示叶节点对象,叶节点没有子节点
class Leaf:Component { public Leaf(string name):base(name) {} public override void Add(Component c) //由于叶节点没有再增加分枝和树叶,所以Add和Remove方法实现 { Console.WriteLine("Cannot add to a leaf"); //它没有意义,但这样可以消除叶节点和枝节点对象在抽象层次的区别 } // 它们具备完全一致的接口 public override void Remove(Component c) { Console.WriteLine("Cannot remove to a leaf"); } public override void Display(int depth) { //叶节点的具体方法,此处是显示其名称和级别 Console.WriteLine(); } }
Composite定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如增加Add和删除Remove
class Composite:Component { private List children=new List(); public Composite(string name):base(name) {} public override void Add(Component c) { children.add(c); } public override void Remove(Component c) { children.Remove(c); } public override void Display(int depth) { //显示枝节点名称,并对其下级进行遍历 Console.WriteLine(new string('-',depth)+name); foreach(Component component in children) { component.Display(depth+2); } } }
客户端代码,能通过Component接口操作组合部件的对象
static void Main(string[] args) { Component root=new Component("root"); root.Add(new Leaf("Leaf A"));//生成树根root,根上长出两叶 root.Add(new Leaf("Leaf B"));//LeafA与LeafB Composite comp=new Composite("Componsite X"); comp.Add(new Leaf("Leaf XA")); comp.Add(new Leaf("Leaf XB")); root.Add(comp); Composite comp2=new Composite("Composite XY"); comp2.Add(new Leaf("Leaf XYA")); comp2.Add(new Leaf("Leaf XYB")); comp.Add(comp2); //根部又长出两页LeafC和LeafD,可惜LeafD没有长牢,被风吹走了 root.Add(new Leaf("Leaf c")); Leaf leaf=new Leaf("Leaf D"); root.Add(leaf); root.Remove(leaf); root,Display(1);//显示大树的样子 }
显示结果:
-root
---leaf A
---leaf B
---Composite X
-----Leaf XA
-----Leaf XB
-----Composite XY
-------Composite XYA
-------Composite XYB
---Leaf c
大B:“现在你能用代码以组合模式,试写一下我给我女朋友买生日礼物。”
小A:“OK”
代码:
using System; using System.Collections.Generic; using System.Text; namespace Composite { interface IGift { void Pay(); void Add(IGift gift); } class GiftSingle : IGift { private string m_name; public GiftSingle(string name) { m_name = name; } public void Add(IGift gift) { } public void Pay() { Console.WriteLine("我买了" + m_name + "!hoho~~"); } }; class GiftComposite : IGift { private string m_name; List m_gifts; public GiftComposite() { m_name = string.Empty; m_gifts = new List(); } public void Add(IGift gift) { m_gifts.Add(gift); } public void Pay() { foreach(IGift gift in m_gifts) { gift.Pay(); } } }; class Program { static void Main(string[] args) { //20岁生日,那时的MM还很单纯~~ Console.WriteLine("lalala~20岁生日来咯------------------------------------------"); IGift singleGift20 = new GiftSingle("手表"); singleGift20.Pay(); //22岁生日,MM变得狡诈" 了~~ Console.WriteLine("heiheihei~22岁生日来咯---------------------------------------"); IGift compositeGift22 = new GiftComposite(); //打包,打包!我要把所有喜欢的礼物打包成“一套”~ compositeGift22.Add(new GiftSingle("手机")); compositeGift22.Add(new GiftSingle("DC")); compositeGift22.Add(new GiftSingle("DV")); compositeGift22.Pay(); //24岁生日………………天哪! Console.WriteLine("hiahiahia~24岁生日来咯--------------------------------------"); //先逛商场一层~买化妆品! IGift compositeGift24 = new GiftComposite(); //打包,打包! compositeGift24.Add(new GiftSingle("香水")); compositeGift24.Add(new GiftSingle("指甲油")); compositeGift24.Add(new GiftSingle("眼影")); //然后来到二层,看中了一套衣服~ IGift singleGift24 = new GiftSingle("衣服"); //因为只能买“一件”,所以“狡诈”的MM再次打包。。。 IGift totalGifts = new GiftComposite(); //我包,我包,我包包包! totalGifts.Add(compositeGift24); totalGifts.Add(singleGift24); totalGifts.Pay(); } } }
大B:“嘿嘿!不错喔!”