首页 > 编程 > C++ > 正文

深入剖析设计模式中的组合模式应用及在C++中的实现

2020-05-23 14:07:35
字体:
来源:转载
供稿:网友
这篇文章主要介绍了设计模式中的组合模式应用及在C++中的实现,组合模式可以清晰地反映出递归构建树状的组合结构,需要的朋友可以参考下
 

组合模式将对象组合成树形结构以表示“部分-整体”的层次结构。C o m p o s i t e 使得用户对单个对象和组合对象的使用具有一致性。

模式图:

设计模式,组合模式,C++

适用场景:

  • 你想表示对象的部分-整体层次结构。
  • 你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

举例:

namespace FactoryMethod_DesignPattern{  using System;  using System.Collections;  abstract class Component   {    protected string strName;    public Component(string name)    {      strName = name;    }    abstract public void Add(Component c);      public abstract void DumpContents();        // other operations for delete, get, etc.  }  class Composite : Component  {    private ArrayList ComponentList = new ArrayList();        public Composite(string s) : base(s) {}    override public void Add(Component c)    {      ComponentList.Add(c);    }    public override void DumpContents()    {      // First dump the name of this composite node      Console.WriteLine("Node: {0}", strName);      // Then loop through children, and get then to dump their contents      foreach (Component c in ComponentList)      {        c.DumpContents();      }    }  }  class Leaf : Component  {    public Leaf(string s) : base(s) {}    override public void Add(Component c)    {      Console.WriteLine("Cannot add to a leaf");    }    public override void DumpContents()    {      Console.WriteLine("Node: {0}", strName);    }  }  /// <summary>  ///  Summary description for Client.  /// </summary>  public class Client  {    Component SetupTree()    {      // here we have to create a tree structure,       // consisting of composites and leafs.         Composite root = new Composite("root-composite");      Composite parentcomposite;      Composite composite;      Leaf leaf;      parentcomposite = root;      composite = new Composite("first level - first sibling - composite");      parentcomposite.Add(composite);      leaf = new Leaf("first level - second sibling - leaf");      parentcomposite.Add(leaf);      parentcomposite = composite;       composite = new Composite("second level - first sibling - composite");      parentcomposite.Add(composite);      composite = new Composite("second level - second sibling - composite");      parentcomposite.Add(composite);      // we will leaf the second level - first sibling empty, and start       // populating the second level - second sibling       parentcomposite = composite;       leaf = new Leaf("third level - first sibling - leaf");      parentcomposite.Add(leaf);            leaf = new Leaf("third level - second sibling - leaf");      parentcomposite.Add(leaf);      composite = new Composite("third level - third sibling - composite");      parentcomposite.Add(composite);      return root;    }    public static int Main(string[] args)    {          Component component;      Client c = new Client();      component = c.SetupTree();      component.DumpContents();      return 0;    }  }}


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

合成模式的实现根据所实现接口的区别分为两种形式,分别称为安全模式和透明模式。合成模式可以不提供父对象的管理方法,但合成模式必须在合适的地方提供子对象的管理方法(诸如:add、remove、getChild等)。

透明方式

 

作为第一种选择,在Component里面声明所有的用来管理子类对象的方法,包括add()、remove(),以及getChild()方法。这样做的好处是所有的构件类都有相同的接口。在客户端看来,树叶类对象与合成类对象的区别起码在接口层次上消失了,客户端可以同等同的对待所有的对象。这就是透明形式的合成模式。

这个选择的缺点是不够安全,因为树叶类对象和合成类对象在本质上是有区别的。树叶类对象不可能有下一个层次的对象,因此add()、remove()以及getChild()方法没有意义,是在编译时期不会出错,而只会在运行时期才会出错。

安全方式

第二种选择是在Composite类里面声明所有的用来管理子类对象的方法。这样的做法是安全的做法,因为树叶类型的对象根本就没有管理子类对象的方法,因此,如果客户端对树叶类对象使用这些方法时,程序会在编译时期出错。

这个选择的缺点是不够透明,因为树叶类和合成类将具有不同的接口。

这两个形式各有优缺点,需要根据软件的具体情况做出取舍决定。

安全式的合成模式实现: 只有composite有Add ,remove,delete等方法.

以下示例性代码演示了安全式的合成模式代码:

// Composite pattern -- Structural example using System;using System.Text;using System.Collections;// "Component"abstract class Component{ // Fields protected string name; // Constructors public Component( string name ) {  this.name = name; } // Operation public abstract void Display( int depth );}// "Composite"class Composite : Component{ // Fields private ArrayList children = new ArrayList(); // Constructors public Composite( string name ) : base( name ) {} // Methods public void Add( Component component ) {  children.Add( component ); } public void Remove( Component component ) {  children.Remove( component ); } public override void Display( int depth ) {  Console.WriteLine( new String( '-', depth ) + name );  // Display each of the node's children  foreach( Component component in children )   component.Display( depth + 2 ); }}// "Leaf"class Leaf : Component{ // Constructors public Leaf( string name ) : base( name ) {} // Methods public override void Display( int depth ) {  Console.WriteLine( new String( '-', depth ) + name ); }}/// <summary>/// Client test/// </summary>public class Client{ public static void Main( string[] args ) {  // Create a tree structure  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 ); }}

 透明式的合成模式实现: 每个里都有add,remove等修改方法.
以下示例性代码演示了安全式的合成模式代码:

// Composite pattern -- Structural example using System;using System.Text;using System.Collections;// "Component"abstract class Component{ // Fields protected string name; // Constructors public Component( string name ) { this.name = name; } // Methods abstract public void Add(Component c); abstract public void Remove( Component c ); abstract public void Display( int depth );}// "Composite"class Composite : Component{ // Fields private ArrayList children = new ArrayList(); // Constructors public Composite( string name ) : base( name ) {} // Methods public override void Add( Component component ) { children.Add( component ); }  public override void Remove( Component component ) { children.Remove( component ); }  public override void Display( int depth ) {   Console.WriteLine( new String( '-', depth ) + name );  // Display each of the node's children  foreach( Component component in children )   component.Display( depth + 2 ); }}// "Leaf"class Leaf : Component{ // Constructors public Leaf( string name ) : base( name ) {} // Methods public override void Add( Component c ) { Console.WriteLine("Cannot add to a leaf"); } public override void Remove( Component c ) { Console.WriteLine("Cannot remove from a leaf"); } public override void Display( int depth ) { Console.WriteLine( new String( '-', depth ) + name ); }}/// <summary>/// Client test/// </summary>public class Client{ public static void Main( string[] args ) {  // Create a tree structure  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 ); }}

实例

再看看一个完整些的例子:

#include <iostream> #include <string> #include <list> using namespace std;  class Component { protected:   string name; public:   Component(string name)     :name(name)   {  }   virtual void AddComponent(Component *component) {  }   virtual void RemoveComponent(Component *component) {  }   virtual void GetChild(int depth)  { } };  class Leaf: public Component { public:   Leaf(string name)     :Component(name)   {  }   void AddComponent(Component *component)   {     cout<<"Leaf can't add component"<<endl;   }   void RemoveComponent(Component *component)   {     cout<<"Leaf can't remove component"<<endl;   }   void GetChild(int depth)   {     string _tmpstring(depth, '-');     cout<<_tmpstring<<name<<endl;   } };  class Composite:public Component { private:   list<Component*> _componets;  public:   Composite(string name)     :Component(name)   { }   void AddComponent(Component *component)   {     _componets.push_back(component);   }   void RemoveComponent(Component *component)   {     _componets.remove(component);   }   void GetChild(int depth)   {     string tmpstring (depth, '-');     cout<<tmpstring<<name<<endl;     list<Component*>::iterator iter = _componets.begin();     for(; iter != _componets.end(); iter++)     {       (*iter)->GetChild(depth + 2);     }   } };  int main() {   Composite *root = new Composite("root");   Leaf *leaf1 = new Leaf("leaf1");   Leaf *leaf2 = new Leaf("leaf2");   root->AddComponent(leaf1);   root->AddComponent(leaf2);    Composite *lay2 = new Composite("layer2");   Leaf *leaf4 = new Leaf("leaf4");   lay2->AddComponent(leaf4);    Composite *lay1 = new Composite("layer1");   Leaf *leaf3 = new Leaf("leaf3");   lay1->AddComponent(leaf3);   lay1->AddComponent(lay2);    root->AddComponent(lay1);    root->GetChild(1);   cout<<endl;   lay1->GetChild(1);   cout<<endl;   lay2->GetChild(1);    delete root;   delete lay1;   delete lay2;   delete leaf1;   delete leaf2;   delete leaf3;   delete leaf4;   system("pause");   return 0; } 

输出:

设计模式,组合模式,C++



发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表