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

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

模式图:

适用场景:

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

举例:

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++
, 设计模式
组合模式
c语言深入剖析、c语言深入剖析班、c语言实现排列组合、c语言实现组合、深入剖析android系统,以便于您获取更多的相关知识。

时间: 2024-08-03 18:21:00

深入剖析设计模式中的组合模式应用及在C++中的实现_C 语言的相关文章

设计模式中的组合模式在JavaScript程序构建中的使用_基础知识

定义 组合,顾名思义是指用包含多个部件的对象创建单一实体. 这个单一实体将用作所有这些部件的访问点,虽然这大大简化了操作,但也可能具有相当的欺骗性,因为没有哪种隐性方式明确表明该组合包含多少部件. 组合模式的目标是解耦客户程序与复杂元素内部架构,使得客户程序对待所有子元素都一视同仁. 每个子节点都可以使复杂的存在,对于父节点来说,不需要知道子节点的复杂性或者实现子节点的复杂性,只需要关注子节点的特定方法,便可以使用子节点.简化了父和子之间的关系. 对于子节点来说也是一样的,过多的接口暴露有时候也

iOS应用开发中运用设计模式中的组合模式的实例解析_IOS

何为组合模式?    组合模式让我们可以把相同基类型的对象组合到树状结构中,其中父节点包含同类型的子节点.换句话说,这种树状结构形成"部分--整体"的层次结构.什么是"部分--整体"的层次结构呢?它是既包含对象的组合又包含叶节点的单个对象的一种层次结构.每个组合体包含的其他节点,可以是叶节点或者其他组合体.这种关系在这个层次结构中递归重复.因为每个组合或叶节点有相同的基类型,同样的操作可应用于它们中的每一个,而不必在客户端作类型检查.客户端对组合与叶节点进行操作时可

Android设计模式系列之组合模式_Android

Android中对组合模式的应用,可谓是泛滥成粥,随处可见,那就是View和ViewGroup类的使用.在android UI设计,几乎所有的widget和布局类都依靠这两个类. 组合模式,Composite Pattern,是一个非常巧妙的模式.几乎所有的面向对象系统都应用到了组合模式. 1.意图 将对象View和ViewGroup组合成树形结构以表示"部分-整体"的层次结构(View可以做为ViewGroup的一部分). 组合模式使得用户对单个对象View和组合对象ViewGrou

Android设计模式系列之组合模式

Android中对组合模式的应用,可谓是泛滥成粥,随处可见,那就是View和ViewGroup类的使用.在android UI设计,几乎所有的widget和布局类都依靠这两个类. 组合模式,Composite Pattern,是一个非常巧妙的模式.几乎所有的面向对象系统都应用到了组合模式. 1.意图 将对象View和ViewGroup组合成树形结构以表示"部分-整体"的层次结构(View可以做为ViewGroup的一部分). 组合模式使得用户对单个对象View和组合对象ViewGrou

.NET中的设计模式三:组合模式

设计 组合模式(Composite)是一种"结构型"模式(Structural).结构型模式涉及的对象为两个或两个以上,表示对象之间的活动,与对象的结构有关. 先举一个组合模式的小小例子: 如图:系统中有两种Box:Game Box和Internet Box,客户需要了解者两个类的接口分别进行调用.为了简化客户的工作,创建了XBox类,程序代码如下: GameBox的代码: public class GameBox { public void PlayGame() { Console.

C# 设计模式系列教程-组合模式_C#教程

1. 概述 将对象组合成树形结构以表示"部分-整体"的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性. 2. 解决的问题 当希望忽略单个对象和组合对象的区别,统一使用组合结构中的所有对象(将这种"统一"性封装起来). 3. 组合模式中的角色 3.1 组合部件(Component):它是一个抽象角色,为要组合的对象提供统一的接口. 3.2 叶子(Leaf):在组合中表示子节点对象,叶子节点不能有子节点. 3.3 合成部件(Composite):定义有枝

【设计模式系列】--组合模式

在前面的博文中,小编介绍了三个工厂模式,三世同堂,各司其职,各有千秋,今天我们继续来学习设计模式的相关知识,今天这篇博文,我们继续来学习设计模式的相关知识,今天这篇博文小编主要和小伙伴们来学习组合模式.小编会从什么是组合模式.组合模式的结构图.组合模式的角色和职责以及结合相关的deom来进行讲解. 一.什么是组合模式 组合模式,英文名字叫Composite,是结构型的设计模式,通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树,将对象组合成树形结构以表示"部分-整体"

.net设计模式实例之组合模式(Composite Pattern)

一.组合模式简介(Brief Introduction) 组合模式,将对象组合成树形结构以表示"部分-整体"的层次结构,组合模式使得用户 对单个对象和组合对象的使用具有一致性. 二.解决的问题(What To Solve) 解决整合与部分可以被一致对待问题. 三.组合模式分析(Analysis)1.组合模式结构 Component类:组合中的对象声明接口,在适当情况下,实现所有类共有接口的行为.声 明一个接口用于访问和管理Component的子部件 Leaf类:叶节点对象,叶节点没有子

设计模式中的迭代器模式在Cocoa Touch框架中的使用_IOS

基本理解迭代器模式(Iterrator):提供一个方法顺序访问一个聚合对象中的各个元素,而又不暴露该元素的内部表示. 当你访问一个聚合对象,而且不管这些对象是什么都需要遍历的时候,你就应该考虑用迭代器模式. 你需要对聚集有多种方式遍历时,可以考虑用迭代器模式. 迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据. 迭代器定义了一个用于访问集合元素并记录当前元素的接口. 不同的迭代器可以执行不同的迭代策略.外