一.介绍
组合模式(Composite Pattern)。属于结构型模式。将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
二.实现
举个例子,我们写前端有用上html标签(抽象构件),这个标签分为双标签(树枝构件)和单标签(树叶构件),在写html时,双标签可以包括双标签和单标签,单标签不能包括任何标签。无论写什么标签,都是写html。这种情况就可以使用组合模式来实现。
//抽象构件(Component)角色 //html标签 public abstract class Component { public virtual string Name { get; set; } public virtual string Name2 { get; set; } public abstract void Add(Component child); public abstract void Remove(Component child); public abstract void Display(int depth = 0); } //树叶构件(Leaf)角色 //单标签 public class Leaf : Component { public override void Add(Component child) { throw new NotImplementedException(); } public override void Display(int depth = 0) { Console.WriteLine(new String('-', depth * 2) + Name); } public override void Remove(Component child) { throw new NotImplementedException(); } } //树枝构件(Composite)角色 //双标签 public class Composite : Component { private List<Component> children = new List<Component>(); public override void Add(Component child) { if (child != null) children.Add(child); } public override void Display(int depth = 0) { Console.WriteLine(new String('-', depth * 2) + Name); children.ForEach(c => { c.Display(depth + 1); }); Console.WriteLine(new String('-', depth * 2) + Name2); } public override void Remove(Component child) { if (child != null) children.Remove(child); } } //调用 public static void Main(string[] args) { //定义html标签 Component html = new Composite { Name = "<html>", Name2 = "</html>" }; //header标签及里面的标签 var header = new Composite { Name = "<header>", Name2 = "</header>" }; header.Add(new Leaf { Name = "<img id='logo' />" }); header.Add(new Leaf { Name = "<input id='B' />" }); //div标签及里面的标签 var content = new Composite { Name = "<div>", Name2 = "</div>" }; var banner = new Composite { Name = "<div id='banner'>", Name2 = "</div>" }; banner.Add(new Leaf { Name = "<img />" }); content.Add(banner); //footer标签 var footer = new Composite { Name = "<footer>", Name2 = "</footer>" }; //html标签包括的标签 html.Add(header); html.Add(content); html.Add(footer); //输出 html.Display(1); }
输出内容。
三.总结
优点:
1.组合模式使得客户端可以一致地处理对象和对象容器,无需关系处理的单个对象,还是组合的对象容器。
2.将“客户代码与复杂的对象容器结构”解耦。
3.可以更容易地往组合对象中加入新的构件。
缺点:
1.使得设计更加复杂。客户端需要花更多时间去理解对象之间的层级关系。