大话设计模式之组合模式

将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象好人组合对象的使用具有一致性。


 

//Component为组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为。
//声明一个借口用于访问和管理Component的子部件
abstractclass Component
{
    protected string name;
 
    public Component(string name)
    {
        this.name = name;
    }
 
    //使用Add和Remove来提供增加或删除树叶或树枝的功能
    public abstract void Add(Component c);
    public abstract void Remove(Component c);
    public abstract void Display(int depth);
};
 
//Leaf在组合中表示叶节点对象,叶节点没有子节点
class Leaf:Component
{
    public Leaf(string name) :base(name)
    {}
 
    public override void Add(Component c)
    {
        //叶子节点无法再增加分支和树叶,所以Add和Remove方法实现也没有意义,但这样可以消除叶节点和枝节点对象在抽象层次的区别,他们具有完全一致的接口
        Console.WriteLine("Cannot add toa  leaf");
    }
 
    public override void Remove(Component c)
    {
        Console.WriteLine("Cannot add toa  leaf");
    }
 
    public override void Display(int depth)
    {
        Console.WriteLine(new String('-', depth) + name);   //这里指 depth个 ‘-’, 后跟一个名字
    }
};
 
//枝节点,存储子部件
class Composite : Component
{
    //一个子对象集合存储其下的枝节点和叶节点
    private List<Component> children = new List<Component>();
 
    public Composite(string name) :base(name)
    {}
 
    public override void Add(Component c)
    {
        children.Add(c);
    }
 
    public abstract void Remove(Component c)
    {
        children.Remove(c);
    }
 
    public abstract void Display(int depth)
    {
        Console.WriteLine(new string('-', depth) + name);
        foreach (Component component inchildren)
        {
            component.Display(depth + 2);
        }
    }
};
 
//客户端
void main()
{
    Composite root = new Composite("root");
    root.Add(new Leaf("Leaf A"));
    root.Add(new Leaf("Leaf B"));
 
    Composite comp = new Composite("Composite X");
    comp.Add(new Leaf("Leaf XA"));
    comp.Add(new Leaf("Leaf XB"));
 
    root.Add(comp);
 
    Composite comp2 = new Composite("Composite XY");
    comp2.Add(new Leaf("Leaf XYA"));
    comp2.Add(new Leaf("Leaf XYB"));
 
    root.Add(comp2);
 
    root.Add(new Leaf("Leaf C"));
 
    Leaf leaf = new Leaf("Leaf D");
    root.Add(leaf);
    root.Remove(leaf);
 
    root.Display(1);
}


 

运行结果如下:

 

在叶节点中实现Add和Remove功能是没有意义的,我们可以在Component中去除这两个功能,而在Composite中单独添加这两个功能,这叫安全模式,当然这样子有好也有不好的地方。

 

何时使用?

    当你发现需求中是体现部分与整体层次的结构时候,以及你希望用户可以忽略组合对象与单个对象的不同,统一的使用组合结构中的所有对象时。

 

下面,给出一个具体的例子,关于总公司、公司部分、分公司的公司管理系统:


abstractclass Company
{
    private 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 Duty(Company c);       //职责
};
 
class ConcretCompany : Company
{
    private List<Company> children = newList<Company>();
 
    public ConcretCompany(string name) :base(name)
    {}
 
    public abstract void Add(Company c)
    {
        children.Add(c);
    }
 
    public abstract void Remove(Company c)
    {
        children.Remove(c);
    }
 
    public abstract void Display(int depth)
    {
        Console.WriteLine(new string('-', depth) + name);
        foreach(Component component in children)
        {
            component.Display(depth + 2);
        }
    }
 
    public abstract void Duty(Company c)
    {
        foreach(Component component in children)
        {
            component.Duty();
        }
    }
};
 
//人力资源部
class HRDep :Company
{
    public HRDep(string name) :base(name)
    {}
 
    public abstract void Add(Company c)
    {}
 
    public abstract void Remove(Company c)
    {}
 
    public abstract void Display(int depth)
    {
        Console.WriteLine(new String('-', depth) + name);
    }
 
    public abstract void Duty(Company c)
    {
        Console.WriteLine("{0} 招聘", name);
    }
};
 
//其他部门
class OTDep :Company
{
    public OTDep(string name) :base(name)
    {}
 
    public abstract void Add(Company c)
    {}
 
    public abstract void Remove(Company c)
    {}
 
    public abstract void Display(int depth)
    {
        Console.WriteLine(new String('-', depth) + name);
    }
 
    public abstract void Duty(Company c)
    {
        Console.WriteLine("{0} 其他", name);
    }
};
 
void main()
{
    //...
}

 

 

组合模式这样就定义了包含公司的部门和分公司。

基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,不断递归下去,客户代码中,任何用到基本对象的地方都可以使用组合对象了

    让客户可以一致的使用组合结构和单个对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值