组合模式

组合模式(Composite Pattern)
 
定义
    组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
 
组合模式(Composite Pattern) 结构图
 
Component为组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component的子部件
abstract   class  Component 
{
    
protected   string  name;
    
public  Component( string  name)
    {
        
this .name = name;
    }
    
    
public   abstract   void  Add(component c); // 通常都用Add和Remove方法来提供增加或移出树叶或树枝的功能
     public   abstract   void  Remove(Component c);
    
public   abstract   void  Display( in  depth);
}
  Leaf在组合中表示叶节点对象,叶节点没有子节点
class  Leaf:Component
{
    
public  Leaf( string  name): base (name)
    {}
    
    
public   override   void  Add(Component c) // 由于叶节点没有再增加分枝和树叶,所以Add和Remove方法实现     
    {
        Console.WriteLine(
" Cannot add to a leaf " );它没有意义,但这样可以消除叶节点和枝节点对象在抽象层次的区别        
    }                                            它们具备完全一致的接口   
    
    
public   override   void  Remove(Component c)
    {
        Console.WriteLine(
" Cannot remove to a leaf " );
    }
    
public   override   void  Display( int  depth)
    {
        
// 叶节点的具体方法,此处是显示其名称和级别
        Console.WriteLine();
    }
}
  Composite定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如增加Add
和删除Remove
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   override   void  Remove(Component c)
    {
        children.Remove(c);
    }
    
    
public   override   void  Display( int  depth)
    {
// 显示枝节点名称,并对其下级进行遍历
        Console.WriteLine( new   string ( ' - ' ,depth) + name);
        
foreach (Component component  in  children)
        {
            component.Display(depth
+ 2 );
        }
    }
}
  客户端代码,能通过Component接口操作组合部件的对象
static   void  Main( string [] args)
{
    Component root
= new  Component( " root " );
    root.Add(
new  Leaf( " Leaf A " )); // 生成树根root,根上长出两叶    
    root.Add( new  Leaf( " Leaf B " )); // LeafA与LeafB
    
    Composite comp
= new  Composite( " Componsite 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 " ));
    comp.Add(comp2);
    
    
// 根部又长出两页LeafC和LeafD,可惜LeafD没有长牢,被风吹走了
    root.Add( new  Leaf( " Leaf c " ));
    
    Leaf leaf
= new  Leaf( " Leaf D " );
    root.Add(leaf);
    root.Remove(leaf);
    root,Display(
1 ); // 显示大树的样子
}
  显示结果:
- root
--- leaf A
--- leaf B
--- Composite X
----- Leaf XA
----- Leaf XB
----- Composite XY
------- Composite XYA
------- Composite XYB
--- Leaf c
  适用场景
   当需求中是体现部分与整体层次的结构时,以及希望用户可以忽略组合对象  与单个对象的不同时,统一地使用组合结构中的所有对象时,就应该考虑用组合模式了

组合模式的优点:
   组合模式定义了包含基本对象和组合对象的类层次结构。 基本对象可以被组合成更复杂的组合 对象,而这个组合对象又可以被组合,这样不断地递归下去,客户代码中,任何用到基本对象的 地方都可以使用组合对象 了。 用户不用关心到底是处理一个叶节点还是处理一个组合组件, 也就是用不着为定义组合而写一些选择判断语句了,简单地说就是组合模式让客户可以一致地 使用 组合结构和单个对象。
 
 透明方式: 也就是说在Component中声明所有用来管 理子对象的方法中,其中包括Add、Remove 等。这样实现Component接口的所有子类都具备了Add和Remove。这样做的好处就是叶节 点 和枝节点对于外界没有区别,它们具备完全一致的行为接口。但问题也很明显,因为Leaf 类本身不具备Add()、Remove()方法的功能,所以 实现它是没有意义的。
 
 安全方式: 也就是在Component接口中不去声明Add和Remove方法,那么子类的Leaf也不需要去实现它,而是在 Composite声明所有用来管理子类对象的方法。不过由于不透明,所以树叶和树枝将不具有相同的接口, 客户端的调用需要做相应的判断,带来了不便

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值