设计模式(14)---组合模式

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

一、定义

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

解释:简单来说,编写一个类,该类能作用于整体,并且编写整体中的部分时也能使用该类,而不用做大的更改。

二、UML类图及基本代码

基本代码:

abstractclassComponent

{PRotectedstringname;publicComponent(stringname)

{this.name =name;

}publicabstractvoidAdd(Component component);publicabstractvoidRemove(Component component);publicabstractvoidDisplay(intdepth);

}classLeaf : Component

{publicLeaf(stringname)

:base(name)

{ }publicoverridevoidAdd(Component component)

{

Console.WriteLine("cannot add to a leaf");

}publicoverridevoidRemove(Component component)

{

Console.WriteLine("cannot remove to a leaf");

}publicoverridevoidDisplay(intdepth)

{

Console.WriteLine(newstring('-', depth) +name);

}

}classComposite : Component

{privateIList<Component> children =newList<Component>();publicComposite(stringname)

:base(name)

{ }publicoverridevoidAdd(Component component)

{

children.Add(component);

}publicoverridevoidRemove(Component component)

{

children.Remove(component);

}publicoverridevoidDisplay(intdepth)

{

Console.WriteLine(newstring('-', depth) +name);foreach(Component componentinchildren)

{

component.Display(depth+2);

}

}

}

客户端进行调用:

Composite root =newComposite("root");

root.Add(newLeaf("leaf A"));

root.Add(newLeaf("leaf B"));

Composite composite=newComposite("Composite X");

composite.Add(newLeaf("leaf XA"));

composite.Add(newLeaf("leaf XB"));

root.Add(composite);

Composite composite2=newComposite("Composite XY");

composite2.Add(newLeaf("leaf XYA"));

composite2.Add(newLeaf("leaf XYB"));

composite.Add(composite2);

root.Add(newLeaf("leaf C"));

Leaf leaf=newLeaf("Leaf D");

root.Add(leaf);

root.Remove(leaf);

root.Display(1);

View Code

结果如图:

三、透明方式和安全方式

基本代码中,leaf类也有add和remove方法,也就是说Component声明所有用来管理子对象的方法,实现了所有子类都具备其方法的目的。这样做的好处就是叶节点和枝节点对于外界没有区别,它们具备完全一致的行为接口。但因为leaf不具备add和remove的功能,所以实现它是没有意义的。这种方式就是透明方式。

安全方式是叶节点和枝节点不具有相同的接口,由于不够透明,那么客户端调用时需要做相应的判断,带来了不便。所以在实际项目中使用安全方式和透明方式就需要视情况而定。

四、举例说明:

绘制一个图形,该图形由一个复杂图形和两条线段组成。可以自由的移除该图形。

publicabstractclassGraphics

{publicstringName {get;set; }publicGraphics(stringname)

{this.Name =name;

}publicabstractvoidDraw();publicabstractvoidAdd(Graphics graphics);publicabstractvoidRemove(Graphics graphics);

}publicclassLine : Graphics

{publicLine(stringname)

:base(name)

{ }publicoverridevoidDraw()

{

Console.WriteLine("画"+Name);

}publicoverridevoidAdd(Graphics graphics)

{thrownewException("不能向简单图形line添加图形");

}publicoverridevoidRemove(Graphics graphics)

{thrownewException("不能向简单图形line移除图形");

}

}publicclassCircle : Graphics

{publicCircle(stringname)

:base(name)

{ }publicoverridevoidDraw()

{

Console.WriteLine("画"+Name);

}publicoverridevoidAdd(Graphics g)

{thrownewException("不能向简单图形Circle添加其他图形");

}publicoverridevoidRemove(Graphics g)

{thrownewException("不能向简单图形Circle移除其他图形");

}

}publicclassComplexGraphics : Graphics

{privateIList<Graphics> complexGraphicsList =newList<Graphics>();publicComplexGraphics(stringname)

:base(name)

{ }publicoverridevoidDraw()

{foreach(Graphics gincomplexGraphicsList)

{

g.Draw();

}

}publicoverridevoidAdd(Graphics graphics)

{

complexGraphicsList.Add(graphics);

}publicoverridevoidRemove(Graphics graphics)

{

complexGraphicsList.Remove(graphics);

}

}

客户端调用:

ComplexGraphics complexGraphics =newComplexGraphics("一个复杂图形和两条线段组成的复杂图形");

complexGraphics.Add(newLine("线段A"));

ComplexGraphics complexGraphics2=newComplexGraphics("一个圆和一条线组成的复杂图形");

complexGraphics2.Add(newCircle("圆"));

complexGraphics2.Add(newLine("线段B"));

complexGraphics.Add(complexGraphics2);

Line line=newLine("线段C");

complexGraphics.Add(line);

Console.WriteLine("复杂图形的绘制如下:");

Console.WriteLine("----------------------");

complexGraphics.Draw();

Console.WriteLine("复杂图形的绘制完成");

Console.WriteLine("----------------------");

complexGraphics.Remove(line);

Console.WriteLine("移除线段C后,复杂图形的绘制如下:");

Console.WriteLine("---------------------");

complexGraphics.Draw();

Console.WriteLine("复杂图形绘制完成");

Console.WriteLine("---------------------");

View Code

调用结果:

五、优缺点及适用场景

优点:

1)组合模式使得客户端可以一致的处理对象和对象容器,既是叶节点和枝节点。

2)更容易的为组合对象添加新的组件。

3)解耦了客户端与复杂对象。

缺点:

设计更加复杂。

适用场景:

1)需要表示一个对象整体和部分的层次结构

2)用户希望忽略组合对象和单个对象的不同,一致的处理组合对象和单个对象。

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航