C++设计模式11-组合模式----靠着大树好乘凉

定义

 

(GoF《设计模式》):将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

组成

① Component 是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。

② Leaf 在组合中表示叶子结点对象,叶子结点没有子结点。

③ Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。

适用性

 

以下情况下适用Composite模式:

1.你想表示对象的部分-整体层次结构

2.你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

 

例子

我们每天在公司上班,我们的公司其实就是一个树型结构的,最上边是总公司,总公司下面还有很多子公司, 而每个子公司有很很多部门。这样整个大公司就是一颗大树,每个子公司同时也是一颗小叔

首先是公司的抽象接口

[cpp] view plain copy print?

  1. // 公司抽象类   
  2. class Company  
  3. {  
  4. public :  
  5.     Company(std::string name)  
  6.     :m_name(name)  
  7.     {  
  8.     }  
  9.   
  10.     virtual ~Company( )  
  11.     {  
  12.   
  13.     }  
  14.   
  15.     virtual void Add(Company *pCompany)        // 增加子公司  
  16.     {  
  17.   
  18.     }  
  19.   
  20.     virtual void Show(int depth) = 0;               // 显示部门  
  21. protected :  
  22.     std::string m_name;                         // 显示公司名字  
  23.   
  24. };  
// 公司抽象类
class Company
{
public :
    Company(std::string name)
    :m_name(name)
    {
    }

    virtual ~Company( )
    {

    }

    virtual void Add(Company *pCompany)        // 增加子公司
    {

    }

    virtual void Show(int depth) = 0;               // 显示部门
protected :
    std::string m_name;                         // 显示公司名字

};

其次是公司的实现

[cpp] view plain copy print?

  1. // 公司类   
  2. class ConcreteCompany : public Company  
  3. {  
  4. public :  
  5.     ConcreteCompany(std::string name)  
  6.     :Company(name)  
  7.     {  
  8.   
  9.     }  
  10.   
  11.     virtual ~ConcreteCompany( ){ };         // 虚析构函数  
  12.   
  13.     void Add(Company *company)     // 添加子公司  
  14.     {  
  15.         this->m_companyList.push_back(company);        // 将子公司或者部门加入到公司的列表中  
  16.     }  
  17.   
  18.     void Show(int depth)               // 显示公司部门  
  19.     {  
  20.         for(int pos = 0; pos < depth; pos++)  
  21.         {  
  22.             std::cout <<"-";  
  23.         }  
  24.         std::cout <<this->m_name <<std::endl;  
  25.         for(std::list<Company *>::iterator it = this->m_companyList.begin( );  
  26.             it != this->m_companyList.end( );  
  27.             ++it)  
  28.         {  
  29.             (*it)->Show(depth + 2);  
  30.         }  
  31.     }  
  32.   
  33. protected :  
  34.     std::list<Company *> m_companyList;          // 下属公司列表  
  35. };  
// 公司类
class ConcreteCompany : public Company
{
public :
    ConcreteCompany(std::string name)
    :Company(name)
    {

    }

    virtual ~ConcreteCompany( ){ };         // 虚析构函数

    void Add(Company *company)     // 添加子公司
	{
		this->m_companyList.push_back(company);        // 将子公司或者部门加入到公司的列表中
	}

    void Show(int depth)               // 显示公司部门
	{
		for(int pos = 0; pos < depth; pos++)
		{
			std::cout <<"-";
		}
		std::cout <<this->m_name <<std::endl;
		for(std::list<Company *>::iterator it = this->m_companyList.begin( );
			it != this->m_companyList.end( );
			++it)
		{
            (*it)->Show(depth + 2);
		}
	}

protected :
    std::list<Company *> m_companyList;          // 下属公司列表
};

接着是财务部门的实现

[cpp] view plain copy print?

  1. // 财务部门   
  2. class FinaceDepartment : public Company  
  3. {  
  4. public :  
  5.     FinaceDepartment(std::string name)  
  6.     :Company(name)  
  7.     {  
  8.   
  9.     }  
  10.   
  11.     virtual ~FinaceDepartment( )  
  12.     {  
  13.     }  
  14.   
  15.     void Show(int depth)               // 显示公司部门  
  16.     {  
  17.         for(int pos = 0; pos < depth; pos++)  
  18.         {  
  19.             std::cout <<"-";  
  20.         }  
  21.         std::cout <<this->m_name <<std::endl;  
  22.     }  
  23. };  
// 财务部门
class FinaceDepartment : public Company
{
public :
    FinaceDepartment(std::string name)
    :Company(name)
    {

    }

    virtual ~FinaceDepartment( )
    {
    }

	void Show(int depth)               // 显示公司部门
	{
		for(int pos = 0; pos < depth; pos++)
		{
			std::cout <<"-";
		}
		std::cout <<this->m_name <<std::endl;
	}
};

然后是人力资源部门

[cpp] view plain copy print?

  1. // 人力部门   
  2. class HRDepartment : public Company  
  3. {  
  4. public :  
  5.     HRDepartment(std::string name)  
  6.     :Company(name)  
  7.     {  
  8.     }  
  9.   
  10.     virtual ~HRDepartment( ){ };         // 虚析构函数  
  11.   
  12.   
  13.     void Show(int depth)               // 显示公司部门  
  14.     {  
  15.         for(int pos = 0; pos < depth; pos++)  
  16.         {  
  17.             std::cout <<"-";  
  18.         }  
  19.         std::cout <<this->m_name <<std::endl;  
  20.     }  
  21.   
  22. };  
// 人力部门
class HRDepartment : public Company
{
public :
    HRDepartment(std::string name)
    :Company(name)
    {
    }

    virtual ~HRDepartment( ){ };         // 虚析构函数

	void Show(int depth)               // 显示公司部门
	{
		for(int pos = 0; pos < depth; pos++)
		{
			std::cout <<"-";
		}
		std::cout <<this->m_name <<std::endl;
	}

};

最后是客户端代码

[cpp] view plain copy print?

  1. int main()  
  2. {  
  3.     // 总公司  
  4.     Company *root = new ConcreteCompany("总公司");  
  5.   
  6.     Company *rootHR = new HRDepartment("人力资源部");  
  7.     Company *rootFI = new FinaceDepartment("财务部");  
  8.     root->Add(rootHR);  
  9.     root->Add(rootFI);  
  10.   
  11.     // 分公司A  
  12.     Company *left = new ConcreteCompany("分公司A");  
  13.     Company *leftHR = new HRDepartment("分公司A人力资源部");  
  14.     Company *leftFI = new FinaceDepartment("分公司A财务部");  
  15.     left->Add(leftHR);  
  16.     left->Add(leftFI);  
  17.     root->Add(left);  
  18.   
  19.     // 分公司B  
  20.     Company *right = new ConcreteCompany("分公司B");  
  21.     Company *righHR = new HRDepartment("分公司B人力资源部");  
  22.     Company *righFI = new FinaceDepartment("分公司B财务部");  
  23.     right->Add(righHR);  
  24.     right->Add(righFI);  
  25.     root->Add(right);  
  26.   
  27.   
  28.     root->Show(0);  
  29.   
  30.   
  31.     return 0;  
  32. }  
int main()
{
    // 总公司
    Company *root = new ConcreteCompany("总公司");

    Company *rootHR = new HRDepartment("人力资源部");
    Company *rootFI = new FinaceDepartment("财务部");
    root->Add(rootHR);
    root->Add(rootFI);

    // 分公司A
    Company *left = new ConcreteCompany("分公司A");
    Company *leftHR = new HRDepartment("分公司A人力资源部");
    Company *leftFI = new FinaceDepartment("分公司A财务部");
    left->Add(leftHR);
    left->Add(leftFI);
    root->Add(left);

    // 分公司B
    Company *right = new ConcreteCompany("分公司B");
    Company *righHR = new HRDepartment("分公司B人力资源部");
    Company *righFI = new FinaceDepartment("分公司B财务部");
    right->Add(righHR);
    right->Add(righFI);
    root->Add(right);

    root->Show(0);

    return 0;
}

总结

 

组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以像处理简单元素一样来处理复杂元素。

如果你想要创建层次结构,并可以在其中以相同的方式对待所有元素,那么组合模式就是最理想的选择。本章使用了一个文件系统的例子来举例说明了组合模式的用途。在这个例子中,文件和目录都执行相同的接口,这是组合模式的关键。通过执行相同的接口,你就可以用相同的方式对待文件和目录,从而实现将文件或者目录储存为目录的子级元素。

转载:http://blog.csdn.net/gatieme/article/details/21460519

时间: 2024-09-17 09:42:14

C++设计模式11-组合模式----靠着大树好乘凉的相关文章

设计模式——11组合模式(Composite)

11.组合模式(Composite)组合模式有时又叫部分-整体模式在处理类似树形结构的问题时比较方便. 直接来看代码:[java] view plaincopy public class TreeNode { private String name; private TreeNode parent; private Vector children = new Vector(); public TreeNode(String name){ this.name = name; } public St

【设计模式】—— 组合模式Composite

模式意图 使对象组合成树形的结构.使用户对单个对象和组合对象的使用具有一致性. 应用场景 1 表示对象的 部分-整体 层次结构 2 忽略组合对象与单个对象的不同,统一的使用组合结构中的所有对象. 模式结构 [安全的组合模式] 这种组合模式,叶子节点,也就是单个对象不具有对象的控制功能.仅仅有简单的业务操作. 1 package com.xingoo.composite.safe; 2 3 import java.util.ArrayList; 4 import java.util.List; 5

C#设计模式(10)——组合模式(Composite Pattern)

原文:C#设计模式(10)--组合模式(Composite Pattern) 一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象和复合对象在功能上区别,导致在操作过程中必须区分简单对象和复合对象,这样就会导致客户调用带来不必要的麻烦,然而作为客户,它们希望能够始终一致地对待简单对象和复合对象.然而组合模式就是解决这样的问题.下面让我们看看组合模式是

C#设计模式(11)——外观模式(Facade Pattern)

原文:C#设计模式(11)--外观模式(Facade Pattern) 一.引言 在软件开发过程中,客户端程序经常会与复杂系统的内部子系统进行耦合,从而导致客户端程序随着子系统的变化而变化,然而为了将复杂系统的内部子系统与客户端之间的依赖解耦,从而就有了外观模式,也称作 "门面"模式.下面就具体介绍下外观模式. 二.外观模式的详细介绍 2.1 定义 外观模式提供了一个统一的接口,用来访问子系统中的一群接口.外观定义了一个高层接口,让子系统更容易使用.使用外观模式时,我们创建了一个统一的

乐在其中设计模式(C#) - 组合模式(Composite Pattern)

原文:乐在其中设计模式(C#) - 组合模式(Composite Pattern)[索引页][源码下载] 乐在其中设计模式(C#) - 组合模式(Composite Pattern) 作者:webabcd 介绍 将对象组合成树形结构以表示"部分-整体"的层次结构.它使得客户对单个对象和复合对象的使用具有一致性. 示例 有一个Message实体类,使其单个对象和复合对象具有一致性. MessageModel using System;using System.Collections.Ge

温故而知新:设计模式之组合模式(Composite)

场景: 如果想模拟windows的开始菜单,分析一下会发现里面的菜单项:有些有子菜单,有些则没有:因此大体可以将菜单类分为二类,设计代码如下:   /// <summary> /// 菜单的显示接口 /// </summary> public interface IMenu { void Show(); } /// <summary> /// 菜单基类 /// </summary> public class MenuBase { public string

设计模式:组合模式(Composite)

将对象组合成属性结构以表示"部分-整体"的层次结构.组合使得用户和单个对象和组合对象的使用具有一致性. 组合模式设计的角色: 1. Component:是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为.声明一个接口用于访问和管理Component. 2. Leaf:在组合中表示叶子节点对象,叶子节点没有子节点. 3. Composite:定义树枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加和删除等. 举个简单例子(树枝和叶子) 1

C++设计模式之组合模式_C 语言

问题描述 上图,是一个公司的组织结构图,总部下面有多个子公司,同时总部也有各个部门,子公司下面有多个部门.如果对这样的公司开发一个OA系统,作为程序员的你,如何设计这个OA系统呢?先不说如何设计实现,接着往下看,看完了下面的内容,再回过头来想怎么设计这样的OA系统. 什么是组合模式? 在GOF的<设计模式:可复用面向对象软件的基础>一书中对组合模式是这样说的:将对象组合成树形结构以表示"部分-整体"的层次结构.组合(Composite)模式使得用户对单个对象和组合对象的使用

php设计模式 Composite (组合模式)

复制代码 代码如下: <?php /** * 组合模式 * * 将对象组合成树形结构以表示"部分-整体"的层次结构,使得客户对单个对象和复合对象的使用具有一致性 */ abstract class MenuComponent { public function add($component){} public function remove($component){} public function getName(){} public function getUrl(){} p