组合模式(Composite)是一种“结构型”模式(Structural)。结构型模式涉及的对象为两个或两个以上,表示对象之间的活动,与对象的结构有关。组合模式适用于两个或者多个类有相似的形式,或者共同代表某个完整的概念,外界的用户也希望他们合而为一,就可以把这几个类“组合”起来,成为一个新的类,用户只需要调用这个新的类就可以了。
组合模式(Composite)是一种“结构型”模式(Structural)。结构型模式涉及的对象为两个或两个以上,表示对象之间的活动,与对象的结构有关。
组合模式适用于两个或者多个类有相似的形式,或者共同代表某个完整的概念,外界的用户也希望他们合而为一,就可以把这几个类“组合”起来,成为一个新的类,用户只需要调用这个新的类就可以了。
因此,组合模式的意图就是:将对象组合成树形结构以表示“部分-整体”的层次结构。Composite模式使得用户对单个对象和组合对象的使用具有一致性。
组合模式可以使客户端将单纯元素与复合元素同等看待。如文件夹与文件就是合成模式的典型应用。根据模式所实现接口的区别,合成模式可分为安全式和透明式两种。
一、安全式:安全式的合成模式要求管理聚集的方法只出现在树枝构件类中,而不出现在树叶构件类中。
涉及到三个角色:
1、抽象构件(Component):这是一个抽象角色,它给参加组合的对象定义公共的接口及其默认的行为,可以用来管理所有的子对象。合成对象通常把它所包含的子对象当做类型为Component的对象。在安全式的合成模式里,构件角色并不定义出管理子对象的方法,这一定义由树枝构件对象给出。
2、树枝构件(Composite):代表参加组合的有下级子对象的对象。树枝构件类给出所有的管理子对象的方法,如Add(),Remove()等。
3、树叶构件(Leaf):树叶对象是没有下级子对象的对象,定义出参加组合的原始对象的行为。
下面我们来实现它
SafeTreeComponent:抽象构件
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TreeComposite
{
//抽象构件(Component):这是一个抽象角色,它给参加组合的对象定义公共的接口及其默认的行为,
//可以用来管理所有的子对象。要提供一个接口以规范取得和管理下层组件的接口,包括Add(),Remove()。
public interface SafeTreeComponent
{
void Display();
}
}
SafeTreeBranch:树枝构件
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace TreeComposite
{
//安全式的合成模式要求管理聚集的方法只出现在树枝构件类中,而不出现在树叶构件类中
class SafeTreeBranch:SafeTreeComponent
{
protected string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
public SafeTreeBranch(string Name)
{
this.Name = Name;
}
private ArrayList branch = new ArrayList();
public void Display()
{
IEnumerator treeEnumerator = branch.GetEnumerator();
while (treeEnumerator.MoveNext())
{
if (treeEnumerator.Current is SafeTreeBranch)
{
Console.WriteLine("树枝 : "+this.Name);
}
if (treeEnumerator.Current is SafeTreeLeaf)
{
((SafeTreeLeaf)treeEnumerator.Current).Display();
}
}
}
public void Add(SafeTreeComponent stc)
{
branch.Add(stc);
}
public void Remove(SafeTreeComponent stc)
{
branch.Remove(stc);
}
}
}
SafeTreeLeaf:树叶构件
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TreeComposite
{
public class SafeTreeLeaf: SafeTreeComponent
{
protected string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
public SafeTreeLeaf(string Name)
{
this.Name = Name;
}
public void Display()
{
Console.WriteLine("树叶"+this.Name);
}
}
}
二、透明式:透明式的组合模式要求所有的具体构件类,不论树枝构件还是树叶构件,均符合一个固定的接口。
涉及到三个角色:
1、抽象构件(Component):这是一个抽象角色,它给参加组合的对象定义公共的接口及其默认的行为,可以用来管理所有的子对象。要提供一个接口以规范取得和管理下层组件的接口,包括Add(),Remove()。
2、树枝构件(Composite):代表参加组合的有下级子对象的对象。定义出这样的对象的行为。
3、树叶构件(Leaf):树叶对象是没有下级子对象的对象,定义出参加组合的原始对象的行为。树叶对象会给出Add(),Remove()等方法的实现。
下面我们来实现它
TransparentTreeComponent:抽象构件
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TreeComposite
{
//抽象构件(Component):这是一个抽象角色,它给参加组合的对象定义公共的接口及其默认的行为,
//可以用来管理所有的子对象。要提供一个接口以规范取得和管理下层组件的接口,包括Add(),Remove()。
public interface TransparentTreeComponent
{
void Display();
void Add(TransparentTreeComponent treeBranch);
void Remove(TransparentTreeComponent treeBranch);
}
}
TransparentTreeBranch:树枝构件
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace TreeComposite
{
//透明式的合成模式要求所有的具体构件类,不论树枝构件还是树叶构件,均符合一个固定的接口
class TransparentTreeBranch: TransparentTreeComponent
{
protected string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
public TransparentTreeBranch (string Name)
{
this.Name = Name;
}
private ArrayList treeBranch = new ArrayList();
public void Display()
{
IEnumerator treeEnumerator = treeBranch.GetEnumerator();
while (treeEnumerator.MoveNext())
{
if (treeEnumerator.Current is TransparentTreeBranch)
{
Console.WriteLine("树枝 : " + this.Name);
}
if (treeEnumerator.Current is TransparentTreeLeaf)
{
((TransparentTreeLeaf)treeEnumerator.Current).Display();
}
}
}
public void Add(TransparentTreeComponent ttc)
{
treeBranch.Add(ttc);
}
public void Remove(TransparentTreeComponent ttc)
{
treeBranch.Remove(ttc);
}
}
}
TransparentTreeLeaf:树叶构件
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace TreeComposite
{
//透明式的合成模式要求所有的具体构件类,不论树枝构件还是树叶构件,均符合一个固定的接口
class TransparentTreeLeaf:TransparentTreeComponent
{
protected string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
public TransparentTreeLeaf(string Name)
{
this.Name = Name;
}
public void Display()
{
Console.WriteLine(this.Name);
}
public void Add(TransparentTreeComponent ttc) { }
public void Remove(TransparentTreeComponent ttc) { }
}
}
客户端应用代码
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TreeComposite
{
class Program
{
static void Main(string[] args)
{
#region 安全式
SafeTreeBranch sroot = new SafeTreeBranch("Root");
sroot.Add(new SafeTreeLeaf("LeafRoot-1"));
sroot.Add(new SafeTreeLeaf("LeafRoot-2"));
SafeTreeBranch sb1 = new SafeTreeBranch("B1");
sb1.Add(new SafeTreeLeaf("LeafB1-1"));
sb1.Add(new SafeTreeLeaf("LeafB1-2"));
Console.WriteLine("-----------------安全式-----------------------");
Console.WriteLine("安全式Root根下含有");
sroot.Add(sb1);
sroot.Display();
Console.WriteLine("安全式Branch1下含有");
sb1.Display();
#endregion
#region 透明式
TransparentTreeBranch troot = new TransparentTreeBranch("Root");
troot.Add(new TransparentTreeLeaf("LeafRoot-1"));
troot.Add(new TransparentTreeLeaf("LeafRoot-2"));
TransparentTreeBranch tb1 = new TransparentTreeBranch("TB1");
tb1.Add(new TransparentTreeLeaf("LeafTB1-1"));
tb1.Add(new TransparentTreeLeaf("LeafTB1-2"));
Console.WriteLine("-----------------透明式-----------------------");
Console.WriteLine("透明式Root根下含有");
troot.Add(tb1);
troot.Display();
Console.WriteLine("透明式Branch1下含有");
tb1.Display();
Console.ReadLine();
#endregion
}
}
}
程序如下图:
运行效果:
前往:设计模式学习笔记清单