组合模式

o_composite.bmp

 

抽象构件(Component)角色:这是一个抽象角色,它给参加组合的对象定义出公共的接口及其默认行为,可以用来管理所有的子对象。在安全式的合成模式里,构件角色并不是定义出管理子对象的方法,这一定义由树枝构件对象给出。

树叶构件(Leaf)角色:树叶对象是没有下级子对象的对象,定义出参加组合的原始对象的行为。

树枝构件(Composite)角色:代表参加组合的有下级子对象的对象。树枝对象给出所有的管理子对象的方法,如add()、remove()、getChild()等。

 

Composite类型的对象可以包含其它Component类型的对象。换而言之,Composite类型对象可以含有其它的树枝(Composite)类型或树叶(Leaf)类型的对象。从名称可以看出树枝可以拥有树叶,树枝哟。

这样我们可以延伸如:Component-----公司,Leaf------部门,Composite-----分公司。

          Component-----菜单,Leaf------子菜单,Composite-----主菜单。

Composite和Component是部分和整体的关系

组合模式中,是将“AddRemove等和对象容器相关的方法定义在表示抽象对象的Component中,还是将其定义在表示对象容器的Composite中,是一个关乎透明性安全性的两难问题,需要仔细权衡。这里有可能违背面向对象的单一职责原则,但是对于这种特殊结构,这又是必须付出的代价。

组合模式分透明方式,安全方式

透明方式:

树叶类对象和合成类对象对于外界没有区别,具备完全一致的行为接口。但是可以看见缺点是:leaf应该没有行为接口的(Add,Move等)。leaf等于多做了无用功。所以要下一种方式。

 

class Component
{
publicvirtual void Add(Component c);
  virtual  void Remove( Component c );
  virtual  void Display( int depth );
}

class Composite : Component
{
  public// Methods
     void Add( Component component )
  { children.Add( component ); }
  
    void Remove( Component component )
  { children.Remove( component ); }
  
    void Display( int depth )
  { 
  }

 private:
     ArrayList children = new ArrayList();
}


class Leaf : Component
{
  public// Methods
     void Add( Component component )
  { children.Add( component ); }
  
    void Remove( Component component )
  { children.Remove( component ); }
  
    void Display( int depth )
  { 
  }
}
 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 );

    root.Add( new Leaf( "Leaf C" ));

    // Add and remove a leaf
    Leaf l = new Leaf( "Leaf D" );
    root.Add( l );
    root.Remove( l );

    // Recursively display nodes
    root.Display( 1 );
  }
}

 

 

安全方式:

在Composite类里面声明所有的用来管理子类对象的方法。这样的做法是安全的做法,因为树叶类型的对象根本就没有管理子类对象的方法,因此,如果客户端对树叶类对象使用这些方法时,程序会在编译时期出错。这个选择的缺点是不够透明,因为树叶类和合成类将具有不同的接口。

 class Component
{
  public :
  virtual void Display( int depth );
}

class Composite : Component
{
public:
    void Add( Component component )
    {
        children.Add( component );
    }
    void Remove( Component component )
    {
      children.Remove( component );
    }
    void Display( int depth )
    {
    }
private:
   ArrayList children = new ArrayList();
}

class Leaf: Component
{
public:
    void Display( int depth )
    {
    }
}

main函数见上面。


Composite 中保存了所有旗下的树叶树枝对象,这样调用display时,可以循环调用


Composite 模式通过和Decorator 模式有着类似的结构图,但是Composite 模式旨在构造类,而Decorator模式重在不生成子类即可给对象添加职责。Decorator模式重在修饰,而Composite 模式重在表示。

 

 

posted @ 2013-07-09 22:36  风啊  阅读(151)  评论(0)    收藏  举报