类关系图
类角色说明
· 抽象构件(Component)角色:这是一个抽象角色,它给参与组合的对象规定一个接口。这个角色给出共有接口及其默认行为。
· 树叶构件(Leaf)角色:代表参加组合的树叶对象。一个树叶对象没有下级子对象。
· 树枝构件(Composite)角色:代表参加组合的有子对象的对象,并给出树枝构件对象的行为。有管理子对象的方法,并有存储管理子对象的属性。
意图
合成模式有时又叫做部分-整体模式(Part-Whole)。合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式可以使客户端将单纯元素与复合元素同等看待。
适用性
合成模式的实现根据所实现接口的区别分为两种形式,分别称为安全模式和透明模式。合成模式可以不提供父对象的管理方法,但合成模式必须在合适的地方提供子对象的管理方法(诸如:add、remove、getChild等)。
透明方式---将管理子类对象的方法(add,remove,getchild)声明在接口(抽象构件)中,那么继承于接口的树叶构件和树枝构件都会有那些方法的痕迹。优点:客户端使用的时候不用接口统一。缺点:因为树叶构件没有子类对象,所以不应该有管理子类对象的方法,所以运行的时候应该有错误提示。所以客户端调用这些方法的时候,编译期不提示错误,而运行期就应该有错误提示。
安全方式---将管理子类对象的方法声明在树枝构件中。这样客户端调用这些方法的时候,如果是树叶构件类调用这些方法那么编译期就会提示错误。
泡妞的例子
COMPOSITE—Mary今天过生日。“我过生日,你要送我一件礼物。”“嗯,好吧,去商店,你自己挑。”“这件T恤挺漂亮,买,这条裙子好看,买,这个包也不错,买。”“喂,买了三件了呀,我只答应送一件礼物的哦。”“什么呀,T恤加裙子加包包 ,正好配成一套呀,小姐,麻烦你包起来。”“……”,MM都会用Composite模式了,你会了没有??
泡妞的代码
using System;
using System.Collections;
public abstract class 抽象礼物
{
protected string name;
public 抽象礼物(string thename)
{
name=thename;
}
public abstract void 买();
}
//树叶构件 不应该有子类对象管理方法
public class 真实礼物:抽象礼物
{
public 真实礼物(string thename):base(thename)
{
}
public override void 买()
{
Console.WriteLine(name+"挺漂亮的,买了!");
}
}
//树枝构件 应该有子类对象管理方法
public class 礼包:抽象礼物
{
private ArrayList 礼物组 = new ArrayList(); //用以存贮子类对象的属性
public 礼包(string thename):base(thename)
{
}
public void 看中(真实礼物 礼物)
{
礼物组.Add(礼物);
}
public void 剔除(真实礼物 礼物)
{
礼物组.Remove(礼物);
}
public override void 买()
{
foreach( 真实礼物 礼物 in 礼物组 )
礼物.买();
}
}
public class 商场
{
public static void Main()
{
Console.WriteLine("Mary:我过生日,你要送我一件礼物!");
Console.WriteLine("7in10:嗯,好吧,去商店,你自己挑。");
真实礼物 T恤=new 真实礼物("T恤");
真实礼物 裙子=new 真实礼物("裙子");
真实礼物 包包=new 真实礼物("包包");
礼包 一套礼物=new 礼包("一套礼物");
一套礼物.看中(T恤);
一套礼物.看中(裙子);
一套礼物.看中(包包);
一套礼物.买();
Console.WriteLine("7in10:喂,买了三件了呀,我只答应送一件礼物的哦。");
Console.WriteLine("Mary:什么呀,T恤加裙子加包包 ,正好配成一套呀,小姐,麻烦你包起来。");
Console.WriteLine("7in10:……偶这个月伙食费…………^_^!");
}
}合成模式
合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式就是一个处理对象的树结构的模式。合成模式把部分与整体的关系用树结构表示出来。合成模式使得客户端把一个个单独的成分对象和由他们复合而成的合成对象同等看待。
使用合成模式时考虑的几个问题
1. 明显的给出父对象的引用。在子对象里面给出父对象的引用,可以很容易的遍历所有父对象。有了这个引用,可以方便的应用责任链模式。
2. 在通常的系统里,可以使用享元模式实现构件的共享,但是由于合成模式的对象经常要有对父对象的引用,因此共享不容易实现。
3. 有时候系统需要遍历一个树枝结构的子构件很多次,这时候可以考虑把遍历子构件的结果暂时存储在父构件里面作为缓存。
4. 关于使用什么数据类型来存储子对象的问题,在示意性的代码中使用了ArrayList,在实际系统中可以使用其它聚集或数组等。
5. 客户端尽量不要直接调用树叶类中的方法,而是借助其父类(Component)的多态性完成调用,这样可以增加代码的复用性。
说明
这个模式用树的结构最好理解和记忆了.
一个树结构由两种节点组成:树枝节点和树叶节点。树枝节点可以有子节点,而一个树叶节点不可以有子节点。如果是非子节点那么就应该有对子节点的管理方法,这个就是例子中的礼包,而子节点就是礼物.把节点抽象出来,如果这个抽象节点设计有管理节点的方法那就是透明方式,如果抽象节点没有对管理节点的方法接口,而是把这些方法的定义与实现都放在了非子节点中,就是安全方式.


浙公网安备 33010602011771号