遂宁建设机械网站,网站一般用什么语言,怎么把在微企点做响应式网站,wordpress的页面链接错乱动机(Motivate): 组合模式有时候又叫做部分-整体模式#xff0c;它使我们树型结构的问题中#xff0c;模糊了简单元素和复杂元素的概念#xff0c;客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。意图(Intent): 将对象组合…动机(Motivate): 组合模式有时候又叫做部分-整体模式它使我们树型结构的问题中模糊了简单元素和复杂元素的概念客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。意图(Intent): 将对象组合成树形结构以表示“部分-整体”的层次结构。Composite模式使得用户对单个对象和组合对象的使用具有一致性。 -----------《设计模式》GOF 结构图(Struct): 生活中的例子 适用性 1你想表示对象的部分-整体层次结构 2你希望用户忽略组合对象与单个对象的不同用户将统一地使用组合结构中的所有对象。代码实现 这里我们用绘图这个例子来说明Composite模式通过一些基本图像元素直线、圆等以及一些复合图像元素由基本图像元素组合而成构建复杂的图形树。在设计中我们对每一个对象都配备一个Draw()方法在调用时会显示相关的图形。可以看到这里复合图像元素它在充当对象的同时又是那些基本图像元素的一个容器。先看一下基本的类结构图 图中橙色的区域表示的是复合图像元素。 示意性代码 1 public abstract class Graphics 2 { 3 protected string _name; 4 5 public Graphics(string name) 6 { 7 this._name name; 8 } 9 public abstract void Draw();10 }11 12 public class Picture : Graphics13 {14 public Picture(string name)15 : base(name)16 { }17 public override void Draw()18 {19 //20 }21 22 public ArrayList GetChilds()23 { 24 //返回所有的子对象25 }26 }而其他作为树枝构件实现代码如下 1 public class Line:Graphics 2 { 3 public Line(string name) 4 : base(name) 5 { } 6 7 public override void Draw() 8 { 9 Console.WriteLine(Draw a _name.ToString());10 }11 }12 13 public class Circle : Graphics14 {15 public Circle(string name)16 : base(name)17 { }18 19 public override void Draw()20 {21 Console.WriteLine(Draw a _name.ToString());22 }23 }24 25 public class Rectangle : Graphics26 {27 public Rectangle(string name)28 : base(name)29 { }30 31 public override void Draw()32 {33 Console.WriteLine(Draw a _name.ToString());34 }35 }现在我们要 对该图像元素进行处理在客户端程序中需要判断返回对象的具体类型到底是基本图像元素还是复合图像元素。如果是复合图像元素我们将要用递归去处理 然而这种处理的结果却增加了客户端程序与复杂图像元素内部结构之间的依赖那么我们如何去解耦这种关系呢我们希望的是客户程序可以像处理基本图像元素一 样来处理复合图像元素这就要引入Composite模式了需要把对于子对象的管理工作交给复合图像元素为了进行子对象的管理它必须提供必要的Add()Remove()等方法类结构图如下 示意代码 1 public abstract class Graphics 2 { 3 protected string _name; 4 5 public Graphics(string name) 6 { 7 this._name name; 8 } 9 public abstract void Draw();10 public abstract void Add();11 public abstract void Remove();12 }13 14 public class Picture : Graphics15 {16 protected ArrayList picList new ArrayList();17 18 public Picture(string name)19 : base(name)20 { }21 public override void Draw()22 {23 Console.WriteLine(Draw a _name.ToString());24 25 foreach (Graphics g in picList)26 {27 g.Draw();28 }29 }30 31 public override void Add(Graphics g)32 {33 picList.Add(g);34 }35 public override void Remove(Graphics g)36 {37 picList.Remove(g);38 }39 }40 41 public class Line : Graphics42 {43 public Line(string name)44 : base(name)45 { }46 47 public override void Draw()48 {49 Console.WriteLine(Draw a _name.ToString());50 }51 public override void Add(Graphics g)52 { }53 public override void Remove(Graphics g)54 { }55 }56 57 public class Circle : Graphics58 {59 public Circle(string name)60 : base(name)61 { }62 63 public override void Draw()64 {65 Console.WriteLine(Draw a _name.ToString());66 }67 public override void Add(Graphics g)68 { }69 public override void Remove(Graphics g)70 { }71 }72 73 public class Rectangle : Graphics74 {75 public Rectangle(string name)76 : base(name)77 { }78 79 public override void Draw()80 {81 Console.WriteLine(Draw a _name.ToString());82 }83 public override void Add(Graphics g)84 { }85 public override void Remove(Graphics g)86 { }87 }这样引入Composite模式后客户端程序不再依赖于复合图像元素的内部实现了。然而我们程序中仍然存在着问题因为LineRectangleCircle已经没有了子对象它是一个基本图像元素因此Add()Remove()的方法对于它来说没有任何意义而且把这种错误不会在编译的时候报错把错误放在了运行期我们希望能够捕获到这类错误并加以处理稍微改进一下我们的程序 1 public class Line : Graphics 2 { 3 public Line(string name) 4 : base(name) 5 { } 6 7 public override void Draw() 8 { 9 Console.WriteLine(Draw a _name.ToString());10 }11 public override void Add(Graphics g)12 { 13 //抛出一个我们自定义的异常14 }15 public override void Remove(Graphics g)16 {17 //抛出一个我们自定义的异常18 }19 }这样改进以后我们可以捕获可能出现的错误做进一步的处理。上面的这种实现方法属于透明式的Composite模式如果我们想要更安全的一种做法就需要把管理子对象的方法声明在树枝构件Picture类里面这样如果叶子节点LineRectangleCircle使用这些方法时在编译期就会出错看一下类结构图 示意代码 1 public abstract class Graphics 2 { 3 protected string _name; 4 5 public Graphics(string name) 6 { 7 this._name name; 8 } 9 public abstract void Draw();10 }11 12 public class Picture : Graphics13 {14 protected ArrayList picList new ArrayList();15 16 public Picture(string name)17 : base(name)18 { }19 public override void Draw()20 {21 Console.WriteLine(Draw a _name.ToString());22 23 foreach (Graphics g in picList)24 {25 g.Draw();26 }27 }28 29 public void Add(Graphics g)30 {31 picList.Add(g);32 }33 public void Remove(Graphics g)34 {35 picList.Remove(g);36 }37 }38 39 public class Line : Graphics40 {41 public Line(string name)42 : base(name)43 { }44 45 public override void Draw()46 {47 Console.WriteLine(Draw a _name.ToString());48 }49 }50 51 public class Circle : Graphics52 {53 public Circle(string name)54 : base(name)55 { }56 57 public override void Draw()58 {59 Console.WriteLine(Draw a _name.ToString());60 }61 }62 63 public class Rectangle : Graphics64 {65 public Rectangle(string name)66 : base(name)67 { }68 69 public override void Draw()70 {71 Console.WriteLine(Draw a _name.ToString());72 }73 }这种方式属于安全式的Composite模式在这种方式下虽然避免了前面所讨论的错误但是它也使得叶子节点和树枝构件具有不一样的接口。这种方式和透明式的Composite各有优劣具体使用哪一个需要根据问题的实际情况而定。通过Composite模式客户程序在调用Draw()的时候不用再去判断复杂图像元素中的子对象到底是基本图像元素还是复杂图像元素看一下简单的客户端调用 1 public class App 2 { 3 public static void Main() 4 { 5 Picture root new Picture(Root); 6 7 root.Add(new Line(Line)); 8 root.Add(new Circle(Circle)); 9 10 Rectangle r new Rectangle(Rectangle);11 root.Add(r);12 13 root.Draw();Composite模式实现要点 1Composite模式采用树形结构来实现普遍存在的对象容器从而将“一对多”的关系转化“一对一”的关系使得客户代码可以一致地处理对象和对象容器无需关心处理的是单个的对象还是组合的对象容器。 2将“客户代码与复杂的对象容器结构”解耦是Composite模式的核心思想解耦之后客户代码将与纯粹的抽象接口——而非对象容器的复内部实现结构——发生依赖关系从而更能“应对变化”。 3Composite模式中是将“Add和Remove等和对象容器相关的方法”定义在“表示抽象对象的Component类”中还是将其定义在“表示对象容器的Composite类”中是一个关乎“透明性”和“安全性”的两难问题需要仔细权衡。这里有可能违背面向对象的“单一职责原则”但是对于这种特殊结构这又是必须付出的代价。ASP.NET控件的实现在这方面为我们提供了一个很好的示范。 4Composite模式在具体实现中可以让父对象中的子对象反向追溯如果父对象有频繁的遍历需求可使用缓存技巧来改善效率。