【设计模式学习笔记】组合模式与桥接模式案例详解(C++实现)

简介: 【设计模式学习笔记】组合模式与桥接模式案例详解(C++实现)

一、组合模式

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. }


相关文章
|
9月前
|
设计模式 存储 缓存
「全网最细 + 实战源码案例」设计模式——享元模式
享元模式(Flyweight Pattern)是一种结构型设计模式,旨在减少大量相似对象的内存消耗。通过分离对象的内部状态(可共享、不变)和外部状态(依赖环境、变化),它有效减少了内存使用。适用于存在大量相似对象且需节省内存的场景。模式优点包括节省内存和提高性能,但会增加系统复杂性。实现时需将对象成员变量拆分为内在和外在状态,并通过工厂类管理享元对象。
358 92
|
6月前
|
设计模式 Java 定位技术
【设计模式】【结构型模式】组合模式(Composite)
一、入门 什么是组合模式 组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构来表示“部分-整体”的层次关系。组合模式使得客户端可以统一处理单个对象和组合对
221 10
|
6月前
|
关系型数据库 Java MySQL
【设计模式】【结构型模式】桥接模式(Bridge)
一、入门 什么是桥接模式? 桥接模式(Bridge Pattern)是一种结构型设计模式,核心思想是将抽象与实现分离,让它们可以独立变化。简单来说,它像一座“桥”连接了两个维度的变化,避免用继承导致代
386 10
|
9月前
|
设计模式 存储 算法
「全网最细 + 实战源码案例」设计模式——命令模式
命令模式(Command Pattern)是一种行为型设计模式,将请求封装成独立对象,从而解耦请求方与接收方。其核心结构包括:Command(命令接口)、ConcreteCommand(具体命令)、Receiver(接收者)和Invoker(调用者)。通过这种方式,命令的执行、撤销、排队等操作更易扩展和灵活。 适用场景: 1. 参数化对象以操作。 2. 操作放入队列或远程执行。 3. 实现回滚功能。 4. 解耦调用者与接收者。 优点: - 遵循单一职责和开闭原则。 - 支持命令组合和延迟执行。 - 可实现撤销、恢复功能。 缺点: - 增加复杂性和类数量。
312 14
「全网最细 + 实战源码案例」设计模式——命令模式
|
9月前
|
设计模式 存储 Java
「全网最细 + 实战源码案例」设计模式——责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,允许将请求沿着处理者链进行发送。每个处理者可以处理请求或将其传递给下一个处理者,从而实现解耦和灵活性。其结构包括抽象处理者(Handler)、具体处理者(ConcreteHandler)和客户端(Client)。适用于不同方式处理不同种类请求、按顺序执行多个处理者、以及运行时改变处理者及其顺序的场景。典型应用包括日志处理、Java Web过滤器、权限认证等。
209 13
「全网最细 + 实战源码案例」设计模式——责任链模式
|
9月前
|
设计模式 算法 开发者
「全网最细 + 实战源码案例」设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,用于定义一系列可替换的算法或行为,并将它们封装成独立的类。通过上下文持有策略对象,在运行时动态切换算法,提高代码的可维护性和扩展性。适用于需要动态切换算法、避免条件语句、经常扩展算法或保持算法独立性的场景。优点包括符合开闭原则、运行时切换算法、解耦上下文与策略实现、减少条件判断;缺点是增加类数量和策略切换成本。示例中通过定义抽象策略接口和具体策略类,结合上下文类实现动态算法选择。
312 8
「全网最细 + 实战源码案例」设计模式——策略模式
|
9月前
|
设计模式 SQL 算法
「全网最细 + 实战源码案例」设计模式——模板方法模式
模板方法模式是一种行为型设计模式,定义了算法的骨架并在父类中实现不变部分,将可变部分延迟到子类实现。通过这种方式,它避免了代码重复,提高了复用性和扩展性。具体步骤由抽象类定义,子类实现特定逻辑。适用于框架设计、工作流和相似算法结构的场景。优点包括代码复用和符合开闭原则,缺点是可能违反里氏替换原则且灵活性较低。
236 7
「全网最细 + 实战源码案例」设计模式——模板方法模式
|
10月前
|
设计模式
「全网最细 + 实战源码案例」设计模式——模式扩展(配置工厂)
该设计通过配置文件和反射机制动态选择具体工厂,减少硬编码依赖,提升系统灵活性和扩展性。配置文件解耦、反射创建对象,新增产品族无需修改客户端代码。示例中,`CoffeeFactory`类加载配置文件并使用反射生成咖啡对象,客户端调用时只需指定名称即可获取对应产品实例。
221 40
|
10月前
|
设计模式 Java 开发者
「全网最细 + 实战源码案例」设计模式——适配器模式
适配器模式(Adapter Pattern)是一种结构型设计模式,通过引入适配器类将一个类的接口转换为客户端期望的另一个接口,使原本因接口不兼容而无法协作的类能够协同工作。适配器模式分为类适配器和对象适配器两种,前者通过多重继承实现,后者通过组合方式实现,更常用。该模式适用于遗留系统改造、接口转换和第三方库集成等场景,能提高代码复用性和灵活性,但也可能增加代码复杂性和性能开销。
369 28
|
9月前
|
设计模式 存储 安全
「全网最细 + 实战源码案例」设计模式——组合模式
组合模式(Composite Pattern)是一种结构型设计模式,用于将对象组合成树形结构以表示“部分-整体”的层次结构。它允许客户端以一致的方式对待单个对象和对象集合,简化了复杂结构的处理。组合模式包含三个主要组件:抽象组件(Component)、叶子节点(Leaf)和组合节点(Composite)。通过这种模式,客户端可以统一处理简单元素和复杂元素,而无需关心其内部结构。适用于需要实现树状对象结构或希望以相同方式处理简单和复杂元素的场景。优点包括支持树形结构、透明性和遵循开闭原则;缺点是可能引入不必要的复杂性和过度抽象。
289 22

热门文章

最新文章