C++设计模式 之 “数据结构” 模式:Composite、Iterator、Chain of Resposibility

  "数据结构"模式
  常常有一些组件在内部具有特定的数据结构,如果让客户程序依赖这些特定的数据结构,将极大地破坏组件的复用。这时候,将这些特定数据结构封装在内部,在外部提供统一的接口,来实现与特定数据结构无关的访问,是一种行之有效的解决方案。

  典型模式
  #Composite
  #Iterator
  #Chain of Resposibility

part 1 Composite 模式

  动机
  #软件在某些情况下,客户代码过多地依赖于对象容器复杂的内部实现结构,对象容器内部实现结构(而非抽象接口)的变化将引起客户代码的频繁变化,带来了代码的维护性、拓展性等弊端。
  #如何将“客户代码与复杂的对象容器结构”解耦?让对象容器自己来实现自身的复杂结构,从而使得客户代码就像处理简单对象一样来处理复杂的对象容器?

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

  结构

  结构 from 《大话设计模式》

  代码 from 《大话设计模式》

  1 #include <iostream>
  2 #include <string>
  3 #include <set>
  4 
  5 using namespace std;
  6 
  7 struct Company;
  8 
  9 using depth = unsigned;
 10 using container = set<Company*>;
 11 
 12 struct Company {
 13     virtual void display(depth d) = 0;
 14     virtual void lineDuty() = 0;
 15 };
 16 
 17 //brunch nood
 18 struct ConcreteCompany : public Company {
 19     container childrens;
 20     string _name;
 21 
 22     ConcreteCompany(string name) : _name(name) {};
 23 
 24     virtual void display(depth d) override {
 25         for (depth i = 0; i < d; i++)
 26             cout << "-";
 27         
 28         cout << _name <<endl;
 29 
 30         for(auto e : this -> childrens)
 31             e->display(d + 1);
 32     }
 33 
 34     virtual void lineDuty() override {
 35         for (auto e : childrens)
 36             e->lineDuty();
 37     }
 38 
 39     void add(Company* c) {
 40         this -> childrens.insert(c);
 41     }
 42 
 43     void remove(Company* c) {
 44         this -> childrens.erase(c);
 45     }
 46 };
 47 
 48 //leaf nood
 49 struct FinanceDepartment : public Company {
 50     string _name;
 51 
 52     FinanceDepartment(string name) : _name(name) {};
 53     
 54     virtual void display(depth d) override {
 55         for (depth i = 0; i < d; i++)
 56             cout << "-";
 57 
 58         cout << _name << endl;
 59     }
 60 
 61     virtual void lineDuty() override {
 62         cout << _name << "财务部 公司收支管理" << endl;
 63     }
 64 };
 65 
 66 //leaf nood
 67 struct HRDepartment : public Company {
 68     string _name;
 69 
 70     HRDepartment(string name) : _name(name) {};
 71 
 72     virtual void display(depth d) override {
 73         for (depth i = 0; i < d; i++)
 74             cout << "-";
 75 
 76         cout << _name << endl;
 77     }
 78 
 79     virtual void lineDuty() override {
 80         cout << _name << "人力资源部 员工招聘培训管理" << endl;
 81     }
 82 };
 83 
 84 int main() {
 85     ConcreteCompany *root = new ConcreteCompany("北京总公司");
 86     root->add(new HRDepartment("总公司人力资源部"));
 87     root->add(new FinanceDepartment("总公司财务部"));
 88 
 89     ConcreteCompany *comp = new ConcreteCompany("上海华东分公司");
 90     comp->add(new HRDepartment("华东分公司人力资源部"));
 91     comp->add(new FinanceDepartment("华东分公司财务部"));
 92     root->add(comp);
 93 
 94     ConcreteCompany *comp1 = new ConcreteCompany("南京办事处");
 95     comp1->add(new HRDepartment("南京办事处人力资源部"));
 96     comp1->add(new FinanceDepartment("南京办事处财务部"));
 97     comp->add(comp1);
 98 
 99     ConcreteCompany *comp2 = new ConcreteCompany("杭州办事处");
100     comp2->add(new HRDepartment("杭州办事处人力资源部"));
101     comp2->add(new FinanceDepartment("杭州办事处财务部"));
102     comp->add(comp2);
103 
104     cout << "结构图" << endl;
105     root->display(1);
106 
107     cout << "职责" << endl;
108     root->lineDuty();
109 
110     return 0;
111 }
View Code

  要点总结
  #Composite模式采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系转化为“一对一”的关系,使得客户代码可以一致地(复用)处理对象和对象容器,无需关心处理的是单个的对象,还是组合的对象容器。
  #将“客户代码与复杂的对象容器结构”解耦的是Composite的核心思想,解耦之后,客户代码将与纯粹的抽象接口——而非对象容器的内部实现结构——发生依赖,从而更能“应对变化”。
  #Composite模式在具体实现中,可以让父对象中的字对象反向追溯;如果父对象有频繁的遍历需求,可以使用缓存技巧来改善效率。

原文地址:https://www.cnblogs.com/fengyubo/p/5017716.html