深入浅出学习设计模式(C#实现)-组合模式

来源:互联网 发布:大氛围大网络大格局 编辑:程序博客网 时间:2024/06/01 21:34

看到组合模式,真的是有一种很开心的感觉。

一.看实例需求

为什么会这么说呢,请看下面的例子:如果有一个项目,为一家在全国许多城市都有分销机构的大公司做办公管理系统,总部包括人力资源/财务/运营等部门,名下的分公司或办事处就上述部门的功能也要有,并且总部,分部,办事处这些都是有组织结构的,不可以平行管理。如下图:


二.解方法利弊

首先,简单的复制是最糟糕的设计

其次,共享功能到各个分公司,即总部/分部/办事处共用一套代码

但是很悲催,上述的两个方法均被毙掉!其一就不用多说了,这样的实现实在是没有意义的,不能为了敲代码而敲代码!其二,也不能满足客户的要求:总部/分部/办事处呈树状结构,是有组织结构的,而不可以平行管理,所以也不可取。

三.组合模式

其实上述情况就是部分与整体的关系,上述情况,虽然有组织结构,但是功能是一样的,所以在这里实际就是整体与部分可以被一致对待的问题。

组合模式(Composite),将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

如下结构图:


 四.树形结构-组合模式代码实现

具体实现代码如下(树形结构,根/分枝/叶结点)

namespace SJ_公司分公司_组合模式_树形结构实现_{    class Program    {        static void Main(string[] args)        {            //生成树根root,根上长出两片叶子,leafA和leafB            Composite root = new Composite("root");            root.Add(new Leaf("Leaf A"));            root.Add(new Leaf("Leaf B"));            //根上长出分枝Composite X,分枝上也有两叶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上再长出分枝CompositeXY ,其分枝上也有两叶leafXYA和leafXYB            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);//显示大树的样子            Console.Read();        }        //组合模式:即将对象组合成树形结构以表示“部分-整体”的层次结构        //虚拟类,Component为组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component的子部件        abstract class Component        {            protected string name;            public Component(string name)            {                this.name = name;            }            //通常用Add和Remove方法类提供增加或移除树叶或树枝的功能            public abstract void Add(Component c);            public abstract void Remove(Component c);            public abstract void Display(int depth);        }        //叶结点(Leaf),叶结点没有子节点        class Leaf : Component        {            public Leaf(string name)                : base(name)            { }            public override void Add(Component c)            {                //由于叶结点没有再增加分枝和树叶,所以Add和Remove方法没有实现的意义,但这样做可以消除叶结点和枝节点对象在抽象层次的区别,                //他们具备完全一致的接口                Console.WriteLine("不能为叶结点再次增加分枝和树叶");            }            //同上            public override void Remove(Component c)            {                Console.WriteLine("Can't remove from a leaf");            }            public override void Display(int depth)            {                //叶结点的具体方法,此处是显示其名称和级别                Console.WriteLine(new string('-', depth) + name);            }        }        //枝节点的行为(Composite)用来存储子部件,在Component接口中实现与子部件有关的操作,比如Add和Remove操作        class Composite : Component        {            //一个字对象集合用来存储其下属的枝节点和叶结点            private List<Component> children = new List<Component>();            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);                }            }        }    }}


0 0