上节课,我谈了设计模式和设计原则。今天,我就具体说说,在 C++ 里,该怎么应用单件、工厂、适配器、代理、职责链等这些经典的设计模式,用到的有 call_once()、make_unique()、async() 等 C++ 工具,希望能够给你一些在实际编码时的启发。
(在接下来学的时候,你也可以同时思考一下它们都符合哪些设计原则,把设计模式和设计原则结合起来学习。)
创建型模式
首先来看看创建型模式,它隐藏了类的实例化过程和细节,让对象的创建独立于系统的其他部分。
创建型模式不多,一共有 5 个,我觉得最有用的是单件和工厂。
单件很简单,要点在于控制对象的创建数量,只能有一个实例,就像是公司的 CEO 一样,有且唯一。
关于它的使用方式、应用场景,存在着一些争议,但我个人觉得,它很好地体现了设计模式的基本思想,足够简单,可以作为范例,用来好好学习模式里的各个要素。
关于单件模式,一个“老生常谈”的话题是“双重检查锁定”,你可能也有所了解,它可以用来避免在多线程环境里多次初始化单件,写起来特别繁琐。
使用第 14 讲里提到的 call_once,可以很轻松地解决这个问题,但如果你想要更省事的话,其实在 C++ 里还有一种方法(C++ 11 之后),就是直接使用函数内部的 static 静态变量。C++ 语言会保证静态变量的初始化是线程安全的,绝对不会有线程冲突。比如:
auto& instance() // 生产单件对象的函数
{
static T obj; // 静态变量
return obj; // 返回对象的引用
}
说完了单件,再来看工厂模式吧。
工厂模式是我个人的“笼统”说法,指的是抽象工厂、工厂方法这两个模式,因为它们就像是现实世界里的工厂一样,专门用来生产对象。
抽象工厂是一个类,而工厂方法是一个函数,在纯面向对象范式里,两者的区别很大。而 C++