设计模式(DesignPattern)问题(Problem)设计一个绘图程序绘制基本图元线对象(Line)、圆对象(Circle)、矩形对象(Rectangle)绘制组合对象(Picture),可包含任意基本图元的组合问题(Problem)+Draw():voidLine+Draw():voidRectangle+Draw():voidCircle+Add():void+Remove():void+GetChilds():ArrayListPicture问题(Problem)publicclassLine{publicvoidDraw(){Console.WriteLine(DrawaLine);}}publicclassCircle{publicvoidDraw(){Console.WriteLine(DrawaCircle);}}publicclassRectangle{publicvoidDraw(){Console.WriteLine(DrawaRectangle);}}问题(Problem)publicclassPicture{protectedArrayListpicList=newArrayList();publicvoidAdd(objectpic){picList.Add(pic);}publicvoidRemove(objectpic){picList.Remove(pic);}publicArrayListGetChilds(){returnpicList;}}问题(Problem)问题(Problem)staticvoidMain(string[]args){Pictureroot=newPicture();Picturebranch1=newPicture();Picturebranch2=newPicture();Lineline1=newLine();Circlecircle1=newCircle();Rectanglerect1=newRectangle();Lineline2=newLine();Circlecircle2=newCircle();Rectanglerect2=newRectangle();root.Add(line1);root.Add(circle1);root.Add(branch1);branch1.Add(line2);branch1.Add(branch2);branch2.Add(circle2);branch2.Add(rect2);root.Add(rect1);Display(root.GetChilds());Console.Read();}问题(Problem)publicstaticvoidDisplay(ArrayListroot){for(inti=0;iroot.Count;i++){if(root[i]isLine){((Line)root[i]).Draw();}elseif(root[i]isCircle){((Circle)root[i]).Draw();}elseif(root[i]isRectangle){((Rectangle)root[i]).Draw();}elseif(root[i]isPicture){Display(((Picture)root[i]).GetChilds());}}}实现判断太麻烦!问题(Problem)+Draw():voidLine+Draw():voidRectangle+Draw():voidCircle+Add():void+Remove():void+GetChilds():ArrayList+Draw():voidPicture+Draw():voidGraphics问题(Problem)publicabstractclassGraphics{publicabstractvoidDraw();}publicclassLine:Graphics{publicoverridevoidDraw(){Console.WriteLine(DrawaLine);}}publicclassCircle:Graphics{publicoverridevoidDraw(){Console.WriteLine(DrawaCircle);}}publicclassRectangle:Graphics{publicoverridevoidDraw(){Console.WriteLine(DrawaRectangle);}}问题(Problem)publicclassPicture:Graphics{protectedArrayListpicList=newArrayList();publicoverridevoidDraw(){Display(picList);}publicvoidDisplay(ArrayListroot){……}}拥有了公共的Draw方法,统一了绘制图形接口staticvoidMain(string[]args){Pictureroot=newPicture();Picturebranch1=newPicture();Picturebranch2=newPicture();Lineline1=newLine();Circlecircle1=newCircle();Rectanglerect1=newRectangle();Lineline2=newLine();Circlecircle2=newCircle();Rectanglerect2=newRectangle();root.Add(line1);root.Add(circle1);root.Add(branch1);branch1.Add(line2);branch1.Add(branch2);branch2.Add(circle2);branch2.Add(rect2);root.Add(rect1);root.Draw();Console.Read();}问题(Problem)代码没有错误,就是优秀的设计吗?问题(Problem)publicoverridevoidDraw(){Display(picList);}publicstaticvoidDisplay(ArrayListroot){for(inti=0;iroot.Count;i++){if(root[i]isLine){((Line)root[i]).Draw();}elseif(root[i]isCircle){((Circle)root[i]).Draw();}elseif(root[i]isRectangle){((Rectangle)root[i]).Draw();}elseif(root[i]isPicture){Display(((Picture)root[i]).GetChilds());}}}依赖于抽象编程,将类型转换为抽象类Graphics问题(Problem)publicclassPicture:Graphics{protectedArrayListpicList=newArrayList();publicoverridevoidDraw(){for(inti=0;ipicList.Count;i++){((Graphics)picList[i]).Draw();}}}问题(Problem)+Draw():voidLine+Draw():voidRectangle+Draw():voidCircle+Add():void+Remove():void+GetChilds():ArrayList+Draw():voidPicture+Draw():voidGraphics这种设计思想就是组合模式我们对于这个图片肯定会非常熟悉,这两幅图片我们都可以看做是一个文件结构,对于这样的结构我们称之为树形结构。在数据结构中我们了解到可以通过调用某个方法来遍历整个树,当我们找到某个叶子节点后,就可以对叶子节点进行相关的操作。我们可以将这颗树理解成一个大的容器,容器里面包含很多的成员对象,这些成员对象即可是容器对象也可以是叶子对象但是由于容器对象和叶子对象在功能上面的区别,使得我们在使用的过程中必须要区分容器对象和叶子对象,但是这样就会给客户带来不必要的麻烦,作为客户而已,它始终希望能够一致的对待容器对象和叶子对象。这就是组合模式的设计动机:组合模式定义了如何将容器对象和叶子对象进行递归组合,使得客户在使用的过程中无须进行区分,可以对他们进行一致的处理。主要内容模式动机与定义1模式结构与分析2模式实例与解析3模式效果与应用4组合模式(CompositePattern)模式动机模式名称:组合模式(CompositePattern)对于树形结构,当容器对象(如文件夹)的某一个方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员对象(可以是容器对象,也可以是叶子对象,如子文件夹和文件)并调用执行。(递归调用)组合模式(CompositePattern)模式动机由于容器对象和叶子对象在功能上的区别,在使用这些对象的客户端代码中必须有区别地对待容器对象和叶子对象,而对于这些对象的区别对待将会使得程序非常复杂。组合模式描述了如何将容器对象和叶子对象进行递归组合,使得用户在使用时无须对它们进行区分,可以一致地对待容器对象和叶子对象,这就是组合模式的模式动机。组合模式(CompositePattern)模式定义组合模式(CompositePattern):组合多个对象形成树形结构以表示“整体—部分”的结构层次。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性。组合模式又可以称为“整体—部分”(Part-Whole)模式,属于对象的结构模式,它将对象组织到树结构中,可以用来描述整体与部分的关系。组合模式(CompositePattern)模式结构+Operation()Leaf+Operation()+Add(inc:Component)+Remove(inc:Component)+GetChild()Component+Operation()+Add(inc:Component)+Remove(inc:Component)+GetChild()CompositeClient组合模式(CompositePattern)典型的Composite对象结构如下图所示:CompositeCompositeLeafLeafLeafLeafLeafLeaf组合模式(CompositePattern)参与者Component:抽象构件(接口或抽象类)组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。Leaf:叶子构件,叶子结点没有子结点。Composite:容器构件,定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。Client:客户类组合模式(CompositePattern)+Draw():voidLine+Draw():voidRectangle+Draw():voidCircle+Add():void+Remove():void+GetChilds():ArrayList+Draw():voidPicture+Draw():voidGraphics关注Picture和Circle类方法的不同组合模式(CompositePattern)思考应该是在Graphic(Component)中声明这些集合操作,并使得这些操作对Leaf类有意义,还是只应该在Picture(Composite)和它的子类中声明并定义这些操作呢?这需要在安全性和透明性之间做出权衡!组合模式(CompositePattern)+Draw():voidLine+Draw():voidRecta