一、组合模式
1. 什么是组合模式
Composite Pattern,组合模式,是一种结构型模式。
组合模式将对象组合成树形结构以表示“整体-部分”的层次结构,并使得用户对单个对象和组合对象的使用具有一致性。
组合模式构造了一个树形的对象结构,并且通过一个属性对象可以可以访问整棵树的对象。
组合模式的三种角色:
- Component:抽象角色,代表树形结构的抽象结点,它定义了所有实现类的统一接口(属性、方法、行为),并提供了访问和管理子结点的接口;简言之,Component定义了Leaf和Composite共同的操作接口,比如增加子结点,删除子结点等行为,是一个抽象基类。
- Leaf:叶子结点,叶子结点中没有子结点,类似于树中的叶子结点,或文件系统中的文件。
- Composite :枝结点,可以存储子结点,并实现子结点的操作,类似于文件系统的文件夹。
2. 组合模式案例
首先定义一个抽象类,为Leaf和Composite提供统一接口,假设要做一个文件系统,文件夹(Composite)中可以放入文件和文件夹,文件(Leaf)中不可以放入任何子结点。
1. class Component 2. { 3. public: 4. virtual void display() = 0; //显示当前文件或文件夹名称 5. virtual void add(Component* node) = 0; //在当前文件夹增加一个文件或文件夹 6. virtual void remove(Component* node) = 0; //在当前文件夹删除一个文件或文件夹 7. virtual vector<Component*>* get_child() = 0; //获取文件夹下属文件或文件夹 8. };
定义一个文件类,文件中不可加入子结点
1. class Leaf : public Component 2. { 3. private: 4. string name; 5. public: 6. Leaf(string name) 7. { 8. this->name = name; 9. } 10. virtual void display() 11. { 12. cout << "Leaf: " << this->name << endl; 13. } 14. virtual void add(Component* node) 15. { 16. cout << "叶子结点,无法加入" << endl; 17. } 18. virtual void remove(Component* node) 19. { 20. cout << "叶子结点,无此操作" << endl; 21. } 22. virtual vector<Component*>* get_child() 23. { 24. cout << "叶子结点,无子结点" << endl; 25. return NULL; 26. } 27. };
定义一个文件夹类,可以加入问价或文件夹
1. class Composite : public Component 2. { 3. private: 4. string name; 5. vector<Component*>* vec; 6. public: 7. Composite(string name) 8. { 9. this->name = name; 10. vec = new vector<Component*>; 11. } 12. ~Composite() 13. { 14. if (vec != NULL) 15. { 16. delete vec; 17. vec = NULL; 18. } 19. } 20. virtual void display() 21. { 22. cout << "Composite: " << this->name << endl; 23. } 24. virtual void add(Component* node) 25. { 26. vec->push_back(node); 27. } 28. virtual void remove(Component* node) 29. { 30. for (vector<Component*>::iterator it = vec->begin(); it != vec->end(); it++) 31. { 32. if (*it == node) 33. { 34. vec->erase(it); 35. } 36. } 37. } 38. virtual vector<Component*>* get_child() 39. { 40. cout << "*" << this->name << " child: " << "*\n"; 41. for (vector<Component*>::iterator it = vec->begin(); it != vec->end(); it++) 42. { 43. (*it)->display(); 44. } 45. return vec; 46. } 47. };
客户端操作
1. int main() 2. { 3. Component* root = NULL; 4. Leaf* l1 = NULL; 5. Leaf* l2 = NULL; 6. Composite* dir = NULL; 7. 8. root = new Composite("/root"); 9. l1 = new Leaf("1.cpp"); 10. l2 = new Leaf("2.cpp"); 11. dir = new Composite("/home"); 12. 13. root->add(dir); 14. dir->add(l1); 15. dir->add(l2); 16. 17. cout << "============" << endl; 18. root->display(); 19. root->get_child(); 20. dir->get_child(); 21. cout << "============" << endl; 22. 23. delete dir; 24. delete l2; 25. delete l1; 26. delete root; 27. 28. system("pause"); 29. return 0; 30. }
二、桥接模式
1. 什么是桥接模式
Bridge Pattern,桥接模式,是一种结构型设计模式。
桥接模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任。它的主要特点是把抽象(abstraction)与行为实现(implementation)分离开来,从而可以保持各部分的独立性以及应对它们的功能扩展。
也就是说,通过桥接模式可以实现抽象部分与实现部分的解耦合,使得抽象和实现都可以独立的发生变化,当通过继承不能实现开闭原则的时候,就可以考虑桥接模式。比如,图形和颜色,把图形设计一个抽象类,颜色设计一个抽象类,然后根据需要的图形去实现图形类,并根据需要的颜色实现颜色类,通过两个抽象类就可以实现颜色和图形的组合。
- Abstractions:抽象类接口,包含了一个对行为实现类Implementor的引用,也就是说二者具有关联关系。
- Refined Abstraction:抽象类接口的实现类,实现了Abstractions中定义的接口,并可以调用Implementor中的方法(包含了Implementor的引用)。
- Implementor:行为实现类接口,定义了一系列操作。
- Concretelmp lementor:具体实现类,实现了Implementor中的操作。
2. 桥接模式案例
实现对不同图形上不同颜色,首先定义两个抽象类,颜色类和图形类
1. class Color 2. { 3. public: 4. virtual void get_color() = 0; 5. }; 6. 7. class Graph 8. { 9. protected: 10. Color* mGraphColor; 11. public: 12. Graph(Color* mGraphColor) 13. { 14. this->mGraphColor = mGraphColor; 15. } 16. virtual void smear_color() = 0; //给图形上色 17. };
定义三个具体的颜色
1. class Red : public Color 2. { 3. public: 4. virtual void get_color() 5. { 6. cout << "红色" << endl; 7. } 8. }; 9. 10. class Blue : public Color 11. { 12. public: 13. virtual void get_color() 14. { 15. cout << "蓝色" << endl; 16. } 17. }; 18. 19. class Yellow : public Color 20. { 21. public: 22. virtual void get_color() 23. { 24. cout << "黄色" << endl; 25. } 26. };
实现具体的图形
1. class Circle : public Graph 2. { 3. public: 4. Circle(Color* mGraphColor) : Graph(mGraphColor) {}; 5. virtual void smear_color() 6. { 7. cout << "圆形 + "; 8. mGraphColor->get_color(); 9. } 10. }; 11. 12. class Triangle : public Graph 13. { 14. public: 15. Triangle(Color* mGraphColor) : Graph(mGraphColor) {}; 16. virtual void smear_color() 17. { 18. cout << "三角形 + "; 19. mGraphColor->get_color(); 20. } 21. };
客户端操作,为图形上色
1. int main() 2. { 3. Color* m_color = NULL; 4. 5. m_color = new Red; 6. Circle* m_circle = new Circle(m_color); 7. m_circle->smear_color(); 8. 9. delete m_color; 10. m_color = new Blue; 11. Triangle* m_triangle = new Triangle(m_color); 12. m_triangle->smear_color(); 13. 14. delete m_color; 15. delete m_triangle; 16. delete m_circle; 17. 18. system("pause"); 19. return 0; 20. }