设计模式9、组合模式 Composite

解释说明:组合多个对象形成树形结构以表示具有部分-整体关系的层次结构。组合模式让客户端可以统一对待单个对象和组合对象。
设计模式9、组合模式 Composite_第1张图片
抽象根节点(Component):定义系统各层次对象的共有方法和属性,可以预先定义一些默认行为和属性
树枝节点(Composite):定义树枝节点的行为,存储子节点,组合树枝节点和叶子节点行程一个树形结构
叶子节点(Left):叶子节点对象,其下再无分支,是系统层次遍历的最小单位
优点:
    可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让 Client 忽略了层次的差异,方便对整个层次结构进行控制。
    Client 可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了 Client 的代码。
    在组合模式中,增加新的叶子构件和容器构件很方便,无须对现有类进行任何修改,符合“开闭原则”。
    为树形结构提供了一种灵活的解决方案,通过递归组合容器对象和叶子对象,可以形成复杂的树形结构,但对树形结构的控制却非常简单。
缺点:
    使设计变得更加抽象,对象的业务规则如果很复杂,则实现组合模式具有很大挑战性,而且不是所有的方法都与叶子对象子类都有关联。
适用场景
    表示对象的“整体-部分”层次结构(树形结构)
    希望用户忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象
#pragma once
#include 
#include 
/****组合模式 Composite******/
using namespace std;
class Component
{
public:
       Component(string name) : m_strName(name) {}
       virtual ~Component() {}
       virtual void Add(Component* cmpt) = 0;  // 添加构件
       virtual void Remove(Component* cmpt) = 0;  // 删除构件
       virtual Component* GetChild(int index) = 0;  // 获取构件
       virtual void Operation(int indent) = 0;  // 显示构件(以缩进的方式)
private:
       Component();  // 不允许
protected:
       string m_strName;
};

#pragma once
#include 
#include "component.h"
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if(p){delete(p); (p)=NULL;} }
#endif
class Composite : public Component
{
public:
       Composite(string name) : Component(name) {}
       virtual ~Composite() {
              while (!m_elements.empty()) {
                     vector::iterator it = m_elements.begin();
                     SAFE_DELETE(*it);
                     m_elements.erase(it);
              }
       }
       void Add(Component* cmpt) {
              m_elements.push_back(cmpt);
       }
       void Remove(Component* cmpt) {
              vector::iterator it = m_elements.begin();
              while (it != m_elements.end()) {
                     if (*it == cmpt) {
                           SAFE_DELETE(cmpt);
                           m_elements.erase(it);
                           break;
                     }
                     ++it;
              }
       }
       Component* GetChild(int index) {
              if (index >= m_elements.size())
                     return NULL;
              return m_elements[index];
       }
       // 递归显示
       void Operation(int indent) {
              string newStr(indent, '-');
              cout << newStr << "+ " << m_strName << endl;
              // 显示每个节点的孩子
              vector::iterator it = m_elements.begin();
              while (it != m_elements.end()) {
                     (*it)->Operation(indent + 2);
                     ++it;
              }
       }
private:
       Composite();  // 不允许
private:
       vector m_elements;
};

#pragma once
#include "component.h"
class Leaf : public Component
{
public:
       Leaf(string name) : Component(name) {}
       virtual ~Leaf() {}
       void Add(Component* cmpt) {
              cout << "Can't add to a Leaf" << endl;
       }
       void Remove(Component* cmpt) {
              cout << "Can't remove from a Leaf" << endl;
       }
       Component* GetChild(int index) {
              cout << "Can't get child from a Leaf" << endl;
              return NULL;
       }
       void Operation(int indent) {
              string newStr(indent, '-');
              cout << newStr << " " << m_strName << endl;
       }
private:
       Leaf();  // 不允许
};

#include "composite.h"
#include "leaf.h"
int main()
{
       // 创建一个树形结构
       // 创建根节点
       Component* pRoot = new Composite("江湖公司(任我行)");
       // 创建分支
       Component* pDepart1 = new Composite("日月神教(东方不败)");
       pDepart1->Add(new Leaf("光明左使(向问天)"));
       pDepart1->Add(new Leaf("光明右使(曲洋)"));
       pRoot->Add(pDepart1);
       Component* pDepart2 = new Composite("五岳剑派(左冷蝉)");
       pDepart2->Add(new Leaf("嵩山(左冷蝉)"));
       pDepart2->Add(new Leaf("衡山(莫大)"));
       pDepart2->Add(new Leaf("华山(岳不群)"));
       pDepart2->Add(new Leaf("泰山(天门道长)"));
       pDepart2->Add(new Leaf("恒山(定闲师太)"));
       pRoot->Add(pDepart2);
       // 添加和删除叶子
       pRoot->Add(new Leaf("少林(方证大师)"));
       pRoot->Add(new Leaf("武当(冲虚道长)"));
       Component* pLeaf = new Leaf("青城(余沧海)");
       pRoot->Add(pLeaf);
       // 小丑,直接裁掉
       pRoot->Remove(pLeaf);
       // 递归地显示组织架构
       pRoot->Operation(1);
       // 删除分配的内存
       SAFE_DELETE(pRoot);
       getchar();
       return 0;
}

 

你可能感兴趣的:(设计模式,设计模式,组合模式)