组合模式(Compisite Pattern)属于结构型设计模式之一,它将一组相似的对象看作一个对象处理,并根据一个树状结构来组合对象,然后提供一个统一的方法去访问相应的对象,以此忽略掉对象与对象集合之间的差别。
安全的组合模式
class Program
{
static void Main(string[] args)
{
Composite root = new Composite("Root");
//构造两个枝干节点
Composite branch1 = new Composite("Branch1");
Composite branch2 = new Composite("Branch2");
//构造两个叶子节点
Leaf leaf1 = new Leaf("Leaf1");
Leaf leaf2 = new Leaf("Leaf2");
//将叶子节点添加到枝干节点中
branch1.Add(leaf1);
branch2.Add(leaf2);
//将枝干节点添加到根节点中
root.Add(branch1);
root.Add(branch2);
//执行方法
root.Show();
Console.Read();
}
}
abstract class Component
{
protected readonly string Name;
public abstract void Show();
public Component(string name)
{
Name = name;
}
}
class Composite : Component
{
private List<Component> Components = new List<Component>();
public Composite(string name) : base(name)
{
}
public override void Show()
{
Console.WriteLine(Name);
foreach(Component component in Components)
{
component.Show();
}
}
public void Add(Component component)
{
Components.Add(component);
}
public void Remove(Component component)
{
Components.Remove(component);
}
public Component Get(int index)
{
return Components[index];
}
}
class Leaf : Component
{
public Leaf(string name) : base(name)
{
}
public override void Show()
{
Console.WriteLine(Name);
}
}
输出结果
Root
Branch1
Leaf1
Branch2
Leaf2
类图
我们发现Main这里直接调用了Component的实现类的方法,如:Add,这都不是Component这个抽象类定义的方法,这样Component定义成抽象类意义就不大了,与依赖倒置原则相违背,于是我们就把Composite类的一些实现放到Component抽象类中。就是透明的组合模式了。
透明的组合模式
class Program
{
static void Main(string[] args)
{
Composite root = new Composite("Root");
//构造两个枝干节点
Composite branch1 = new Composite("Branch1");
Composite branch2 = new Composite("Branch2");
//构造两个叶子节点
Leaf leaf1 = new Leaf("Leaf1");
Leaf leaf2 = new Leaf("Leaf2");
//将叶子节点添加到枝干节点中
branch1.Add(leaf1);
branch2.Add(leaf2);
//将枝干节点添加到根节点中
root.Add(branch1);
root.Add(branch2);
//执行方法
root.Show();
Console.Read();
}
}
abstract class Component
{
protected readonly string Name;
public abstract void Show();
public Component(string name)
{
Name = name;
}
public abstract void Add(Component child);
public abstract void Remove(Component child);
public abstract Component Get(int index);
}
class Composite : Component
{
private List<Component> Components = new List<Component>();
public Composite(string name) : base(name)
{
}
public override void Show()
{
Console.WriteLine(Name);
foreach (Component component in Components)
{
component.Show();
}
}
public override void Add(Component component)
{
Components.Add(component);
}
public override void Remove(Component component)
{
Components.Remove(component);
}
public override Component Get(int index)
{
return Components[index];
}
}
class Leaf : Component
{
public Leaf(string name) : base(name)
{
}
public override void Add(Component child)
{
throw new NotImplementedException("叶子节点没有子节点");
}
public override Component Get(int index)
{
throw new NotImplementedException("叶子节点没有子节点");
}
public override void Remove(Component child)
{
throw new NotImplementedException("叶子节点没有子节点");
}
public override void Show()
{
Console.WriteLine(Name);
}
}
输出结果
Root
Branch1
Leaf1
Branch2
Leaf2
类图
优点与缺点
组合模式的优点:
- 组合模式使得客户端代码可以一致地处理对象和对象容器,无需关系处理的单个对象,还是组合的对象容器。
- 将”客户代码与复杂的对象容器结构“解耦。
- 可以更容易地往组合对象中加入新的构件。
组合模式的缺点:
- 使得设计更加复杂。客户端需要花更多时间理清类之间的层次关系。
本文主要借鉴了《Gof设计模式》