定义:组合多个对象造成树形结构以表示具备部分-总体关系的层次结构。组合模式让客户端能够统一对待单个对象和组合对象。又被成为“部分-总体”(Part-Whole)模式,属于对象结构性模式安全
定义什么的,最枯燥了。简单的来讲,就如咱们鼠标右击新建文件夹同样,在一个磁盘里,咱们能够新建一个文件夹A,也能够新建某个类型的文件a,A和a都在同一目录下,固然,咱们也能够点击进入文件夹A,在A中新建新的文件夹B,也能够在A中新建文件b。只要是文件夹,就能够在里面继续新建文件夹和文件,而文件则只能用来放数据,不能在新建了。ide
固然,也能够经过win+r调出运行,输入cmd(commmand),进入你想查看文件的磁盘,输入tree命令,就能够结构性的查看全部文件。在上述图中能够看出文件结构就如同一棵树,有文件夹,有文件,咱们把文件成为叶子(Laef),由于文件不能再展开了,就如树形结构中叶子是最底层了;把文件夹称为容器(Container),由于文件夹里既能够文件夹,又能够放文件。当想要查看一个磁盘的全部文件时,可使用DFS(深度优先搜索)即递归的对每一个文件夹进行一样的搜索,一条路走到底,当访问到叶子结点时,再退回去访问别的结点。this
1 abstract class Component 2 { 3 public abstract void Add(Component c); 4 public abstract void Remove(Component c); 5 public abstract Component GetChild(int i); 6 public abstract void Operation(); 7 } 8 class Leaf : Component 9 { 10 public override void Add(Component c) 11 { 12 //throw new NotImplementedException();//这里是报错,叶子文件没有此方法的 13 } 14 15 public override void Remove(Component c) 16 { 17 //throw new NotImplementedException();//同上 18 } 19 20 public override Component GetChild(int i ) 21 { 22 //throw new NotImplementedException();//同上 23 return null; 24 } 25 26 public override void Operation() 27 { 28 //对文件的可执行方法 29 } 30 } 31 class Composite : Component 32 { 33 private IList<Component> list = new List<Component>();//这里通链表容器存放文件夹 34 public override void Add(Component c) 35 { 36 list.Add(c); 37 } 38 39 public override void Remoce(Component c) 40 { 41 list.Remove(c); 42 } 43 44 public override Component GetChild(int i ) 45 { 46 return (Component)list(c); 47 } 48 49 public override void Operation() 50 { 51 //递归实现容器中的对文件的方法 52 foreach(Component child in list) 53 { 54 (Component)child.Operation(); 55 } 56 } 57 }
教育机构的OA系统要给各办公室下发公文(IssuedBytheOfficeDoucument),采用组合模式模拟实现spa
分析:从图中能够看出,北京总部,湖南分校,长沙叫教学点,湘潭教学点这几个有子构件,因此它们为文件容器,而教务办公室,行政办公室即为叶子,固然,每一个叶子是不一样的,要区别开。所以咱们定义一个抽象机构类(AbstractInstitutions),其中声明Add,Remove,GetChild和IssuedBytheOfficeDoucument方法。3d
1 abstract class AbstractInstitutions//Component 2 { 3 public abstract void Add(AbstractInstitutions institutions); 4 public abstract void Remove(AbstractInstitutions institutions); 5 public abstract AbstractInstitutions GetChild(int i); 6 public abstract void IssuedBytheOfficeDoucument(); 7 }
教务办公室,有本身的名字,即哪个教务办公室,它只能收到下发的公文code
1 class AcademicAffairsOffice : AbstractInstitutions//Leaf 教务办公室 2 { 3 private string name; 4 public AcademicAffairsOffice(string name) 5 { 6 this.name = name; 7 } 8 public override void Add(AbstractInstitutions institutions) 9 { 10 Console.WriteLine("Can't realize this method!!!"); 11 } 12 13 public override void Remove(AbstractInstitutions institutions) 14 { 15 Console.WriteLine("Can't realize this method!!!"); 16 } 17 18 public override AbstractInstitutions GetChild(int i) 19 { 20 Console.WriteLine("Can't realize this method!!!"); 21 return null; 22 } 23 24 public override void IssuedBytheOfficeDoucument() 25 { 26 Console.WriteLine("issued by the office doucument to the {0}",name); 27 } 28 }
行政办公室和教务办公室相似的实现对象
1 class AdministrationOffice : AbstractInstitutions//Leaf 行政办公室 2 { 3 private string name; 4 public AdministrationOffice(string name) 5 { 6 this.name = name; 7 } 8 9 public override void Add(AbstractInstitutions institutions) 10 { 11 Console.WriteLine("Can't realize this method!!!"); 12 } 13 14 public override void Remove(AbstractInstitutions institutions) 15 { 16 Console.WriteLine("Can't realize this method!!!"); 17 } 18 19 public override AbstractInstitutions GetChild(int i) 20 { 21 Console.WriteLine("Can't realize this method!!!"); 22 return null; 23 } 24 25 public override void IssuedBytheOfficeDoucument() 26 { 27 Console.WriteLine("issued by the office doucument to the {0}", name); 28 } 29 }
容器类中实现抽象构件中的方法,而且要向下属机构下发公文blog
1 class TeachArea : AbstractInstitutions//Composite //教学点 2 { 3 private string name; 4 private IList<AbstractInstitutions> AreaList = new List<AbstractInstitutions>(); 5 6 public TeachArea(String name) 7 { 8 this.name = name; 9 } 10 11 public override void Add(AbstractInstitutions institutions) 12 { 13 AreaList.Add(institutions); 14 } 15 16 public override void Remove(AbstractInstitutions institutions) 17 { 18 AreaList.Remove(institutions); 19 } 20 21 public override AbstractInstitutions GetChild(int i) 22 { 23 return (AbstractInstitutions)AreaList[i]; 24 } 25 26 public override void IssuedBytheOfficeDoucument() 27 { 28 Console.WriteLine("Issue official documents to the {0}", name); 29 foreach (Object obj in AreaList) 30 { 31 ((AbstractInstitutions)obj).IssuedBytheOfficeDoucument(); 32 } 33 } 34 }
Program中,要将全部的机构建立出来,并一一Add到对应的容器中,最后有由北京总部向下发送公文继承
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 AbstractInstitutions BeijingHeadquarters; 6 BeijingHeadquarters = new TeachArea("BeijingHeadquarters"); 7 8 AbstractInstitutions BeijingAcademicAffairsOffice; 9 BeijingAcademicAffairsOffice = new AcademicAffairsOffice("BeijingAcademicAffairsOffice"); 10 AdministrationOffice BeijingAdministrationOffice; 11 BeijingAdministrationOffice = new AdministrationOffice("BeijingAdministrationOffice"); 12 13 AbstractInstitutions HunanPartition; 14 HunanPartition = new TeachArea("HunanPartition"); 15 16 AbstractInstitutions HunanChangshaArea; 17 HunanChangshaArea = new TeachArea("HunanChangshaArea"); 18 19 AbstractInstitutions HunanXiangtanArea; 20 HunanXiangtanArea = new TeachArea("HunanXiangtanArea"); 21 22 AbstractInstitutions HunanAcademicAffairOffice; 23 HunanAcademicAffairOffice = new AcademicAffairsOffice("HunanAcademicAffairOffice"); 24 AbstractInstitutions HunanAdministrationOffice; 25 HunanAdministrationOffice = new AdministrationOffice("HunanAdministrationOffice"); 26 27 Console.WriteLine(); 28 AbstractInstitutions ChangshaAcademicAffairOffice; 29 ChangshaAcademicAffairOffice = new AcademicAffairsOffice("ChangshaAcademicAffairOffice"); 30 31 AbstractInstitutions ChangshaAdministrationOffice; 32 ChangshaAdministrationOffice = new AdministrationOffice("ChangshaAdministrationOffice"); 33 AbstractInstitutions XiangtanAcademicAffairOffice; 34 XiangtanAcademicAffairOffice = new AcademicAffairsOffice("XiangtanAcademicAffairOffice"); 35 36 AbstractInstitutions XiangtanAdministrationOffice; 37 XiangtanAdministrationOffice = new AdministrationOffice("XiangtanAdministrationOffice"); 38 39 HunanChangshaArea.Add(ChangshaAcademicAffairOffice); 40 HunanChangshaArea.Add(ChangshaAdministrationOffice); 41 42 HunanXiangtanArea.Add(XiangtanAcademicAffairOffice); 43 HunanXiangtanArea.Add(XiangtanAdministrationOffice); 44 45 HunanPartition.Add(HunanChangshaArea); 46 HunanPartition.Add(HunanXiangtanArea); 47 HunanPartition.Add(HunanAcademicAffairOffice); 48 HunanPartition.Add(HunanAdministrationOffice); 49 50 BeijingHeadquarters.Add(BeijingAcademicAffairsOffice); 51 BeijingHeadquarters.Add(BeijingAdministrationOffice); 52 BeijingHeadquarters.Add(HunanPartition); 53 BeijingHeadquarters.IssuedBytheOfficeDoucument(); 54 } 55 }
运行结果:递归
在Component中声明全部的方法,这样知足了一致性的原则,即对叶子和容器对象都是同样的处理,不需用再去判断,这个对象是叶子仍是容器啊,若是是容器,能够实现哪些方法,若是是叶子,又只能实现哪些方法。这些判断都不须要。可是,因为叶子也继承了Component的方法,所以不安全,叶子对象不能调用Add,Remove,GetChild的方法,若是运行时调用,会出错,所以要提供错误处理代码(如上述例子中的( Console.WriteLine("Can't realize this method!!!");
Component中没有声明任何方法,而是在Composite中声明并实现,这样作不会由于Leaf调用错误的方法而报错,但缺点是不够透明,即要区别的对待叶子构件和容器构件,可是平常使用是不少的,毕竟安全的每每好不少
上面的例子使用了透明组合模式。