MaoBisheng

Asp.Net(C#) & SQL & Oracle

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

8. Composite 组合模式  2008-8-14

动机(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();//履行职责,不同部门需要履行不同的职责
    }
 
    //具体公司类 实现接口 树枝节点
    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);
        }
    }

运行结果:

结构图:
-北京总公司
---总公司人力资源部
---总公司财务部
---上海华东分公司
-----华东分公司人力资源部
-----华东分公司财务部
-----南京办事处
-------南京办事处人力资源部
-------南京办事处财务部
-----杭州办事处
-------杭州办事处人力资源部
-------杭州办事处财务部

职责:
总公司人力资源部 员工招聘培训管理
总公司财务部 公司财务收支管理
华东分公司人力资源部 员工招聘培训管理
华东分公司财务部 公司财务收支管理
南京办事处人力资源部 员工招聘培训管理
南京办事处财务部 公司财务收支管理
杭州办事处人力资源部 员工招聘培训管理
杭州办事处财务部 公司财务收支管理

 

Composite 的几个要点

Composite模式采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系转化为“一对一”的关系,使得客户代码可以一致地处理对象和对象容器,无需关心处理的是单个的对象,还是组合的对象容器。

将“客户代码与复杂的对象容器结构”解耦是Composite的核心思想,解耦之后,客户代码将与纯粹的抽象接口——而非对象容器的内部实现结构——发生依赖,从而更能“应对变化”。

     Composite模式在具体实现中,可以让父对象中的子对象反向追溯;如果父对象有频繁的遍历需求,可使用缓存技巧来改善效率。

 

 

 

posted on 2008-08-14 18:59  MaoBisheng  阅读(388)  评论(0编辑  收藏  举报