首页 > 代码库 > 组合模式(18)

组合模式(18)

我们来讲一下组合模式:

怎么是组合模式呢?组合模式,将对象组合成树形结构以表示‘部分-整体’的层次结构,组合模式是的用户对单个对象和组合对象的用用具有一致性。

与一个很简单的例子,公司的组织架构,大都是树枝结构的。下面,我们来看一下如何用组合模式写树枝结构。

 1      //接口用于访问和管理Component的子部件
 2     abstract class Component
 3     {
 4 
 5         protected string name;
 6 
 7         public Component(string name)
 8         {
 9             this.name = name;
10         }
11 
12         //通常都用Add 和Remove 方法来提供增加或移除树叶或树枝的功能
13         public abstract void Add(Component c);
14         public abstract void Remove(Component c);
15         public abstract void Display(int depth);
16     }
 1  //Leaf在组合中表示叶节点对象,叶节点没有子节点
 2     class Leaf:Component
 3     {
 4         public Leaf(string name) : base(name)
 5         {
 6         }
 7         //由于叶子没有再增加分支和树叶,所以Add 和Remove 方法实现它没有意义,但这样做可以消除叶节点和枝节点
 8         //在抽象层次的区别,它们具备完全一直的接口
 9         public override void Add(Component c)
10         {
11             Console.WriteLine("Can‘t add to a leaf");
12         }
13 
14         public override void Remove(Component c)
15         {
16             Console.WriteLine("Can‘t remove  from a leaf");
17         }
18 
19         public override void Display(int depth)
20         {
21             Console.WriteLine(new String(-,depth)+name);
22         }
23     }
 1  //Composite定义有枝节点行为,用来储存子部件,在Component接口中实现与子部件有关的操作
 2     //比如增加Add 和 删除 Remove
 3     class Composite:Component
 4     {
 5         //一个子对象集合用来存储其下属的枝节点和叶节点
 6         private List<Component> children = new List<Component>();
 7         public Composite(string name) : base(name)
 8         {
 9         }
10 
11         public override void Add(Component c)
12         {
13             children.Add(c);
14         }
15 
16         public override void Remove(Component c)
17         {
18             children.Remove(c);
19         }
20 
21         public override void Display(int depth)
22         {
23             //显示其枝节点名称,并对其下级进行遍历
24             Console.WriteLine(new String(-,depth)+name);
25             foreach (Component component in children)
26             {
27                 component.Display(depth + 2);
28             }
29         }
30     }

客户端

        public static void Main()
        {
            //生成树根root,根上长出两叶LeafA 和 LeafB
            Composite root = new Composite("root");
            root.Add(new Leaf("Leaf A"));
            root.Add(new Leaf("Leaf B"));

            //根上长出分支CompositX
            //分支上也有两叶LeafXA和LeafXB
            Composite comp = new Composite("Composite X");
            comp.Add(new Leaf("Leaf XA"));
            comp.Add(new Leaf("Leaf XB"));

            root.Add(comp);

            //在Composite X 上在长出分支 Composite XY
            //分支上也有两叶LeafXYA 和 LeafXYB
            Composite comp2 = new Composite("Composite XY");
            comp2.Add(new Leaf("Leaf XYA"));
            comp2.Add(new Leaf("Leaf XYB"));

            comp.Add(comp2);

            root.Add(new Leaf("Leaf C"));

            Leaf leaf = new Leaf("Leaf D");
            root.Add(leaf);
            root.Remove(leaf);

            root.Display(1);
            Console.ReadKey();
        }

结果:

技术分享

好,是不是很简单啊……

那么,什么时候用组合模式呢?当你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式了。

组合模式就先讲到这里,下一篇博文,我们讲 迭代器模式


本系列将持续更新,喜欢的小伙伴可以点一下关注和推荐,谢谢大家的支持

组合模式(18)