1.概述
组合模式(Composite Pattern):组合多个对象形成树形结构以表示具有 部分- 整体 关系的层次结构。组合模式让客户可以统一对待单个对象和组合对象。
又称,部分-整体(Part-Whole)模式,属于对象结构型模式。
2.结构
1.Compoenet(抽象构件):接口或抽象类,为叶子构件和容器构件的父类。包含子类的共有行为和实现。定义了访问及管理它的子构件的方法,如增加子构件、删除子构件、获取子构件等。
2.Leaf(叶子构件):表示叶子构件,它没有子构件,继承实现抽象构件。对于那些访问或管理子构件的方法,可以抛出异常或提示错误等方式处理。
3.Composite(容器构件):表示容器节点对象,继承实现抽象构件,可包含子构件,其子构件可以是容器构件也可以是叶子构件。在其业务方法中可以递归调用其子构件的业务方法。
3.实现
using System.Collections.Generic;
namespace Composite
{
#region 透明组合模式
public abstract class Component
{
public abstract void Add(Component c);
public abstract void Remove(Component c);
public abstract Component GetChild(int i);
public abstract void Operation();
}
public class Leaf : Component
{
public override void Add(Component c)
{
throw new System.NotImplementedException();
}
public override Component GetChild(int i)
{
throw new System.NotImplementedException();
}
public override void Operation()
{
//--Do Operation
}
public override void Remove(Component c)
{
throw new System.NotImplementedException();
}
}
public class Composite : Component
{
private List<Component> components = new List<Component>();
public override void Add(Component c)
{
components.Add(c);
}
public override Component GetChild(int i)
{
return components[i];
}
public override void Operation()
{
foreach (Component item in components)
{
item.Operation();
}
}
public override void Remove(Component c)
{
components.Remove(c);
}
}
public class Client
{
private List<Component> components = new List<Component>();
public void UseMethod()
{
components.Add(new Leaf());
Composite composite1 = new Composite();
composite1.Add(new Leaf());
Composite composite2 = new Composite();
composite2.Add(new Leaf());
composite1.Add(composite2);
components.Add(composite1);
for (int i = 0; i < components.Count; i++)
{
components[i].Operation();
}
}
}
#endregion
#region 安全组合模式
public abstract class SafeComponent
{
public abstract void Operation();
public abstract bool IsLeaf();
}
public class SafeLeaf : SafeComponent
{
public override void Operation()
{
//--Do Operation
}
public override bool IsLeaf()
{
return true;
}
}
public class SafeComposite : SafeComponent
{
private List<SafeComponent> components = new List<SafeComponent>();
public void Add(SafeComponent c)
{
components.Add(c);
}
public void Remove(SafeComponent c)
{
components.Remove(c);
}
public SafeComponent GetChild(int i)
{
return components[i];
}
public override void Operation()
{
foreach (SafeComponent item in components)
{
item.Operation();
}
}
public override bool IsLeaf()
{
return false;
}
}
public class SafeClient
{
private List<SafeComponent> components = new List<SafeComponent>();
public void UseMethod()
{
components.Add(new SafeLeaf());
SafeComposite safeComposite1 = new SafeComposite();
safeComposite1.Add(new SafeLeaf());
SafeComposite safeComposite2 = new SafeComposite();
safeComposite2.Add(new SafeLeaf());
components.Add(safeComposite1);
for (int i = 0; i < components.Count; i++)
{
if (!components[i].IsLeaf())
{
((SafeComposite)components[i]).Add(new SafeLeaf());
}
}
for (int i = 0; i < components.Count; i++)
{
components[i].Operation();
}
}
}
#endregion
}
4.优缺点
(1)组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,让用户忽略了层次的差异,方便对整个结构进行控制。
(2)用户可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了用户代码。
(3)在组合模式中增加新的容器构件和叶子构件都很方便,无须对现有类库进行任何修改,符合开闭原则。
(4)为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子对象和容器对象的递归组合,可以形成复杂的树形结构,但对树形结构的控制却非常简单。
(1)在新增新构件时很难对容器构件中的构件类型进行限制。有时候希望一个容器只能有某些特定的类型的对象,在使用组合模式时,不能依赖类型系统来施加这些约束,因为他们都来自相同的抽象层。在这种情况下,必须通过在运行时进行类型检查来实现,这个过程较为复杂。(我在安全组合模式中的抽象组件类中加了一个抽象bool方法)。