1.设计模式:Adapter(适配器模式)
- 体现:类的复合关系
- 定义:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的类可以一起工作。
- 实现:适配器继承或依赖已有的对象,实现想要的目标接口。
2.C++技巧:Pimpl(编译防火墙)
Pimpl(pointer to implementation, 指向实现的指针)是一种常用的,用来对“类的接口与实现”进行解耦的方法。这个技巧可以避免在头文件中暴露私有细节,因此是促进 API 接口与实现保持完全分离的重要机制。但是 Pimpl 并不是严格意义上的设计模式(它是受制于 C++ 语言特定限制的变通方案),这种惯用法可以看作桥接设计模式的一种特例。
-
体现:类的委托关系(Delegation)
- 委托也可以看做是一种复合,但是它包含的不是对象成员,而是指向对象的指针的成员(composition by reference)
- 类有可能先创建,但是有指针,等到需要用到右边时才创建右边(生命期不同步)
- 左边不用修改,左边只是对外的接口;真正的实现在右边。当左边需要动作时,都是通过调用右边的类来服务的。右边不管怎么变都不影响左边,也就不影响客户端。
-
Pimpl 惯用法:公有类拥有一个私有指针,该指针指向隐藏的实现类,其优点为:
-
降低耦合
-
信息隐藏
-
降低编译依赖,提高编译速度
-
接口与实现分离
-
代码示例:
//用一个指针指向为我们实现所有功能的那个类 class stringRep; class string{ public: string(); string(const char *s); string(const string &s); string & operator=(const string &s1); ~string() private: stringRep *rep; ... }; //比如此段程序,表示左边的一个类 //此段程序表示右边的一个类 namespace{ class stringRep{ friend class string; stringRep(const char *s); ~stringRep(); int count; char *rep; }; }
C++编程技巧: Pimpl - 知乎 (zhihu.com)
编译防火墙——C++的Pimpl惯用法解析_plmpl句柄_haozlee的博客-CSDN博客
3.设计模式:Template Method(模板方法)
定义一个操作中算法的骨架,而将一些操作延迟到子类中。Template Method 使得子类可以不改变一个算法的结构,即可重定义该算法的某些特定步骤。(GOF: 《设计模式》)
-
体现:类的继承关系(虚函数)
-
如下例,基类CDocument中有一个算法,在这个算法中有一个步骤——Serialize()函数被派生类设置为虚函数,然后我用派生类对象调用基类的这个算法时,这就意味着算法的其他部分是基类已经定义好的,我们照旧执行,但执行到Serialieze()函数时,就执行派生类自己重写的这个,这样的好处我们可以在不改变一个算法的基本结构的同时,可以改变某个特定的步骤
4.设计模式:Observer pattern(观察者模式)
-
体现:类的委托和继承
-
定义:定义对象间一种一对多的依赖关系,使得当每一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。
-
内容:观察者模式包含观察目标和观察者两类对象,一个目标可以有任意数目的与之相依赖的观察者,一旦观察目标的状态发生改变,所有的观察者都将得到通知。
-
原理:目标subject类用指向observer类的指针vector来实现绑定或者说添加观察者observer类(其派生类通过隐式转换也可以被添加),这样subject类可以通过遍历指针数组调用每一个指向的对象的update函数来达到消息通知的目的
5.设计模式:Composite(组合模式)
- 体现:类的委托和继承
- 理解:在计算机文件系统中,有文件夹的概念,文件夹里面既可以放入文件也可以放入文件夹,但是文件中却不能放入任何东西。文件夹和文件构成了一种递归结构和容器结构。在容器中既可以放入容器,又可以放入内容,然后在小容器中,又可以继续放入容器和内容。组合模式就是用于创造出这样的结构的。
6.设计模式:prototype(原型模式)
- 体现:类的委托和继承
- Prototype模式提供了一个通过已存在对象进行新对象创建的接口(Clone), Clone()实现和具体的语言相关,在C++中通过拷贝构造函数实现。
- 在GOF的《设计模式:可复用面向对象软件的基础》中是这样说的:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。