8. Composite 组合模式
动机(Motivation)
在某些情况下,客户代码过多地依赖于对象容器复杂的内部实现结构,对象容器内部实现结构(而非抽象接口)的变化将引起客户代码的频繁变化,带来了代码的维护性、扩展性等弊端。
如何将“客户代码与复杂的对象容器结构”解耦?让对象容器自己来实现自身的复杂结构,从而使得客户代码就像处理简单对象一样来处理复杂的对象容器?
意图(Intent)
将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。 ——《设计模式》GoF
基本代码:
Code
例子:
代码实现:
//公司类 抽象类或接口
abstract class Company
{
protected string name;
public Company(string name)
{
this.name = name;
}
public abstract void Add(Company c);//增加
public abstract void Remove(Company c);//移除
public abstract void Display(int depth);//显示
public abstract void LineOfDuty();//履行职责,不同部门需要履行不同的职责
}
abstract class Company
{
protected string name;
public Company(string name)
{
this.name = name;
}
public abstract void Add(Company c);//增加
public abstract void Remove(Company c);//移除
public abstract void Display(int depth);//显示
public abstract void LineOfDuty();//履行职责,不同部门需要履行不同的职责
}
//具体公司类 实现接口 树枝节点
class ConcreteCompany : Company
{
private List<Company> children = new List<Company>();
public ConcreteCompany(string name)
: base(name)
{ }
public override void Add(Company c)
{
children.Add(c);
}
public override void Remove(Company c)
{
children.Remove(c);
}
public override void Display(int depth)
{
Console.WriteLine(new String('-', depth) + name);
foreach (Company component in children)
{
component.Display(depth + 2);
}
}
//履行职责
public override void LineOfDuty()
{
foreach (Company component in children)
{
component.LineOfDuty();
}
}
}
class ConcreteCompany : Company
{
private List<Company> children = new List<Company>();
public ConcreteCompany(string name)
: base(name)
{ }
public override void Add(Company c)
{
children.Add(c);
}
public override void Remove(Company c)
{
children.Remove(c);
}
public override void Display(int depth)
{
Console.WriteLine(new String('-', depth) + name);
foreach (Company component in children)
{
component.Display(depth + 2);
}
}
//履行职责
public override void LineOfDuty()
{
foreach (Company component in children)
{
component.LineOfDuty();
}
}
}
//人力资源部与财务部类 树叶节点
//人力资源部
class HRDepartment : Company
{
public HRDepartment(string name)
: base(name)
{ }
public override void Add(Company c)
{
}
public override void Remove(Company c)
{
}
public override void Display(int depth)
{
Console.WriteLine(new String('-', depth) + name);
}
public override void LineOfDuty()
{
Console.WriteLine("{0} 员工招聘培训管理", name);
}
}
//财务部
class FinanceDepartment : Company
{
public FinanceDepartment(string name)
: base(name)
{ }
public override void Add(Company c)
{
}
public override void Remove(Company c)
{
}
public override void Display(int depth)
{
Console.WriteLine(new String('-', depth) + name);
}
public override void LineOfDuty()
{
Console.WriteLine("{0} 公司财务收支管理", name);
}
}
//人力资源部
class HRDepartment : Company
{
public HRDepartment(string name)
: base(name)
{ }
public override void Add(Company c)
{
}
public override void Remove(Company c)
{
}
public override void Display(int depth)
{
Console.WriteLine(new String('-', depth) + name);
}
public override void LineOfDuty()
{
Console.WriteLine("{0} 员工招聘培训管理", name);
}
}
//财务部
class FinanceDepartment : Company
{
public FinanceDepartment(string name)
: base(name)
{ }
public override void Add(Company c)
{
}
public override void Remove(Company c)
{
}
public override void Display(int depth)
{
Console.WriteLine(new String('-', depth) + name);
}
public override void LineOfDuty()
{
Console.WriteLine("{0} 公司财务收支管理", name);
}
}
运行结果:
结构图:
-北京总公司
---总公司人力资源部
---总公司财务部
---上海华东分公司
-----华东分公司人力资源部
-----华东分公司财务部
-----南京办事处
-------南京办事处人力资源部
-------南京办事处财务部
-----杭州办事处
-------杭州办事处人力资源部
-------杭州办事处财务部
职责:
总公司人力资源部 员工招聘培训管理
总公司财务部 公司财务收支管理
华东分公司人力资源部 员工招聘培训管理
华东分公司财务部 公司财务收支管理
南京办事处人力资源部 员工招聘培训管理
南京办事处财务部 公司财务收支管理
杭州办事处人力资源部 员工招聘培训管理
杭州办事处财务部 公司财务收支管理
-北京总公司
---总公司人力资源部
---总公司财务部
---上海华东分公司
-----华东分公司人力资源部
-----华东分公司财务部
-----南京办事处
-------南京办事处人力资源部
-------南京办事处财务部
-----杭州办事处
-------杭州办事处人力资源部
-------杭州办事处财务部
职责:
总公司人力资源部 员工招聘培训管理
总公司财务部 公司财务收支管理
华东分公司人力资源部 员工招聘培训管理
华东分公司财务部 公司财务收支管理
南京办事处人力资源部 员工招聘培训管理
南京办事处财务部 公司财务收支管理
杭州办事处人力资源部 员工招聘培训管理
杭州办事处财务部 公司财务收支管理
Composite 的几个要点
Composite模式采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系转化为“一对一”的关系,使得客户代码可以一致地处理对象和对象容器,无需关心处理的是单个的对象,还是组合的对象容器。
将“客户代码与复杂的对象容器结构”解耦是Composite的核心思想,解耦之后,客户代码将与纯粹的抽象接口——而非对象容器的内部实现结构——发生依赖,从而更能“应对变化”。
Composite模式在具体实现中,可以让父对象中的子对象反向追溯;如果父对象有频繁的遍历需求,可使用缓存技巧来改善效率。
作者:MaoBisheng
出处:http://maobisheng.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://maobisheng.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。