1 组合模式
定义:将对象组合成树形结构以表示,部分-整体的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
理解:如果需求体现的是某种树形组织关系的话,可以考虑使用组合模式。
作用:希望用户忽略组合对象和单个对象的不同,统一的使用组合结构中的所有对象(封装变化的思想)。
内容:抽象组合对象,叶子对象,组合对象内部的组合对象
UML图:
实现代码:
//抽象的部件类描述将来所有部件共有的行为
public abstract class Component
{
protected string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
//添加部件
public abstract void Add(Component component);
//删除部件
public abstract void Remove(Component component);
//遍历所有子部件
public abstract void eachChild();
}
//组合部件类
public class Leaf : Component
{
//叶子节点不具备添加的能力,所以不实现
public override void Add(Component component)
{
throw new NotImplementedException();
}
//叶子节点不具备添加的能力必然也不能删除
public override void Remove(Component component)
{
throw new NotImplementedException();
}
//叶子节点没有子节点所以显示自己的执行结果
public override void eachChild()
{
Console.WriteLine("{0}执行了..",name);
}
}
//组合类
public class Composite : Component
{
//用来保存组合的部件
List<Component> myList = new List<Component>();
//添加节点 添加部件
public override void Add(Component component)
{
myList.Add(component);
}
//删除节点 删除部件
public override void Remove(Component component)
{
myList.Remove(component);
}
//遍历子节点
public override void eachChild()
{
Console.WriteLine("{0}执行了..", name);
foreach (Component c in myList)
{
c.eachChild();
}
}
}
static void Main(string[] args)
{
//构造根节点
Composite rootComponent = new Composite();
rootComponent.Name = "根节点";
//添加两个叶子几点,也就是子部件
Leaf l = new Leaf();
l.Name = "叶子节点一";
Leaf l1 = new Leaf();
l1.Name = "叶子节点二";
rootComponent.Add(l);
rootComponent.Add(l1);
//遍历组合部件
rootComponent.eachChild();
}
模式参与者:
Component
它是一个抽象角色,为对象的组合提供统一的接口。
为其派生类提供默认的行为。
通过该接口来访问和管理Child Components(节点后继)。
通过该接口来访问Parent Components(节点前驱)。
Leaf
代表参加组合的叶子对象(叶子没有后继)。
定义组成原始对象的行为。
Composite
定义非叶子对象的行为。
实现Component中的孩子操作行为(如:Add(),Remove() 等)。
1.组合模式(Composite)采用树形层次结构来实现对象容器,如:绘图程序例子我们把各种各样的图形添加的Shape中,从而构造起一条对象链,把“一对多”的关系转化“一对一”的层次关系,使得客户代码可以一致地处理对象和对象容器,无需关心处理的是单个的对象,还是组合的对象容器。
2.组合模式(Composite)中,透明方式和安全方式的使用抉择,虽然透明方式有可能违背面向对象的SRP原则(单一职责),而安全方式没有很好的封装变化,但在实际开发时我们要根据具体的情况权衡利弊。
其他:
大家注意到在我们给出的例子中,我们都是把对象一个接一个的链接起来,值就是像是一条对象链,不禁让人想起装饰者模式(Decorator)中的装饰对象链。
组合模式(Composite)和装饰者模式(Decorator)的关系
图5 Decorator中的Composite
通过上图我们可以发现,装饰者模式(Decorator)是通过组合模式(Composite)来构建起一棵对象树,然后通过装饰者的子类来扩展装饰者(即Composite)的行为,从而实现对具体组件装饰行为(即Leaf)。
安全模式:在透明模式基础上把Component中声明所有用来管理子对象的方法移到Composite中,在Composite实现子对象的管理方法,那么Leaf就没有子对象管理方法,这使得Composite和Leaf的行为接口不一致,所以客户端在调用时要知道树叶和树枝对象存在。
图2透明方式的组合模式(Composite)结构图
图3安全方式的组合模式(Composite)结构图
demo:公司和子公司的关系