第45章 现代C++设计模式 45.1 设计模式概述 45.1.1 设计模式的概念 设计模式是在软件设计中针对特定问题的通用、可重用的解决方案。它是在特定环境下解决特定问题的一套被反复使用的、经过分类的、代码设计经验的总结。
45.1.2 设计模式的分类 根据GoF(Gang of Four)的分类,设计模式可以分为三大类:
创建型模式 :处理对象的创建过程
单例模式(Singleton) 工厂方法模式(Factory Method) 抽象工厂模式(Abstract Factory) 建造者模式(Builder) 原型模式(Prototype) 结构型模式 :处理对象之间的组合关系
适配器模式(Adapter) 桥接模式(Bridge) 组合模式(Composite) 装饰器模式(Decorator) 外观模式(Facade) 享元模式(Flyweight) 代理模式(Proxy) 行为型模式 :处理对象之间的通信
观察者模式(Observer) 策略模式(Strategy) 命令模式(Command) 迭代器模式(Iterator) 状态模式(State) 模板方法模式(Template Method) 访问者模式(Visitor) 中介者模式(Mediator) 备忘录模式(Memento) 责任链模式(Chain of Responsibility) 解释器模式(Interpreter) 45.1.3 设计模式的重要性 代码重用 :设计模式提供了经过验证的解决方案,避免重复造轮子可维护性 :设计模式使代码更加清晰、结构化,易于理解和维护可扩展性 :设计模式提供了灵活的架构,易于添加新功能标准化 :设计模式为开发者提供了共同的语言和术语降低风险 :使用经过验证的设计模式可以减少设计错误45.1.4 现代C++中的设计模式 现代C++(C++11及以后)为设计模式的实现提供了许多新特性:
智能指针 :std::unique_ptr、std::shared_ptr 用于资源管理lambda表达式 :用于简化回调和策略模式移动语义 :提高性能,特别是在原型模式和建造者模式中右值引用 :支持移动语义类型推导 :auto 关键字简化代码模板别名 :using 关键字提供更好的类型别名constexpr :编译时计算委托构造函数 :简化构造函数代码继承构造函数 :简化继承关系强类型枚举 :enum class 提供类型安全的枚举45.2 创建型设计模式 45.2.1 单例模式(Singleton) 单例模式确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。
45.2.1.1 传统实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 class Singleton {private : static Singleton* instance; Singleton () { } ~Singleton () { } Singleton (const Singleton&) = delete ; Singleton& operator =(const Singleton&) = delete ; public : static Singleton* getInstance () { if (instance == nullptr ) { instance = new Singleton (); } return instance; } static void destroyInstance () { if (instance != nullptr ) { delete instance; instance = nullptr ; } } void doSomething () { } }; Singleton* Singleton::instance = nullptr ;
45.2.1.2 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <memory> #include <mutex> class Singleton {private : Singleton () { } Singleton (const Singleton&) = delete ; Singleton& operator =(const Singleton&) = delete ; public : static Singleton& getInstance () { static Singleton instance; return instance; } void doSomething () { } };
45.2.1.3 应用场景 配置管理 :全局配置对象日志系统 :全局日志记录器数据库连接池 :管理数据库连接线程池 :管理线程资源45.2.2 工厂方法模式(Factory Method) 工厂方法模式定义了一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
45.2.2.1 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 #include <memory> #include <string> class Product {public : virtual ~Product () = default ; virtual std::string getName () const = 0 ; }; class ConcreteProductA : public Product {public : std::string getName () const override { return "Product A" ; } }; class ConcreteProductB : public Product {public : std::string getName () const override { return "Product B" ; } }; class Creator {public : virtual ~Creator () = default ; virtual std::unique_ptr<Product> createProduct () = 0 ; void someOperation () const { auto product = createProduct (); std::cout << "Using " << product->getName () << std::endl; } }; class ConcreteCreatorA : public Creator {public : std::unique_ptr<Product> createProduct () override { return std::make_unique <ConcreteProductA>(); } }; class ConcreteCreatorB : public Creator {public : std::unique_ptr<Product> createProduct () override { return std::make_unique <ConcreteProductB>(); } }; int main () { std::unique_ptr<Creator> creatorA = std::make_unique <ConcreteCreatorA>(); creatorA->someOperation (); std::unique_ptr<Creator> creatorB = std::make_unique <ConcreteCreatorB>(); creatorB->someOperation (); return 0 ; }
45.2.2.2 应用场景 框架设计 :框架需要由子类决定创建哪种对象插件系统 :根据配置或用户选择创建不同的插件实例数据库访问 :根据不同的数据库类型创建不同的连接对象45.2.3 抽象工厂模式(Abstract Factory) 抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
45.2.3.1 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 #include <memory> #include <string> class AbstractProductA {public : virtual ~AbstractProductA () = default ; virtual std::string getName () const = 0 ; }; class ConcreteProductA1 : public AbstractProductA {public : std::string getName () const override { return "Product A1" ; } }; class ConcreteProductA2 : public AbstractProductA {public : std::string getName () const override { return "Product A2" ; } }; class AbstractProductB {public : virtual ~AbstractProductB () = default ; virtual std::string getName () const = 0 ; }; class ConcreteProductB1 : public AbstractProductB {public : std::string getName () const override { return "Product B1" ; } }; class ConcreteProductB2 : public AbstractProductB {public : std::string getName () const override { return "Product B2" ; } }; class AbstractFactory {public : virtual ~AbstractFactory () = default ; virtual std::unique_ptr<AbstractProductA> createProductA () = 0 ; virtual std::unique_ptr<AbstractProductB> createProductB () = 0 ; }; class ConcreteFactory1 : public AbstractFactory {public : std::unique_ptr<AbstractProductA> createProductA () override { return std::make_unique <ConcreteProductA1>(); } std::unique_ptr<AbstractProductB> createProductB () override { return std::make_unique <ConcreteProductB1>(); } }; class ConcreteFactory2 : public AbstractFactory {public : std::unique_ptr<AbstractProductA> createProductA () override { return std::make_unique <ConcreteProductA2>(); } std::unique_ptr<AbstractProductB> createProductB () override { return std::make_unique <ConcreteProductB2>(); } }; int main () { std::unique_ptr<AbstractFactory> factory1 = std::make_unique <ConcreteFactory1>(); auto productA1 = factory1->createProductA (); auto productB1 = factory1->createProductB (); std::cout << "Factory 1: " << productA1->getName () << ", " << productB1->getName () << std::endl; std::unique_ptr<AbstractFactory> factory2 = std::make_unique <ConcreteFactory2>(); auto productA2 = factory2->createProductA (); auto productB2 = factory2->createProductB (); std::cout << "Factory 2: " << productA2->getName () << ", " << productB2->getName () << std::endl; return 0 ; }
45.2.3.2 应用场景 跨平台应用 :为不同平台创建不同的UI组件主题系统 :为不同主题创建不同的UI元素数据库访问 :为不同数据库创建不同的连接和命令对象45.2.4 建造者模式(Builder) 建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
45.2.4.1 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 #include <memory> #include <string> #include <vector> class Product {public : void addPart (const std::string& part) { parts.push_back (part); } void show () const { std::cout << "Product parts: " << std::endl; for (const auto & part : parts) { std::cout << "- " << part << std::endl; } } private : std::vector<std::string> parts; }; class Builder {public : virtual ~Builder () = default ; virtual void buildPartA () = 0 ; virtual void buildPartB () = 0 ; virtual void buildPartC () = 0 ; virtual std::unique_ptr<Product> getResult () = 0 ; }; class ConcreteBuilder1 : public Builder {public : ConcreteBuilder1 () : product (std::make_unique <Product>()) {} void buildPartA () override { product->addPart ("Part A1" ); } void buildPartB () override { product->addPart ("Part B1" ); } void buildPartC () override { product->addPart ("Part C1" ); } std::unique_ptr<Product> getResult () override { return std::move (product); } private : std::unique_ptr<Product> product; }; class ConcreteBuilder2 : public Builder {public : ConcreteBuilder2 () : product (std::make_unique <Product>()) {} void buildPartA () override { product->addPart ("Part A2" ); } void buildPartB () override { product->addPart ("Part B2" ); } void buildPartC () override { product->addPart ("Part C2" ); } std::unique_ptr<Product> getResult () override { return std::move (product); } private : std::unique_ptr<Product> product; }; class Director {public : void construct (Builder& builder) { builder.buildPartA (); builder.buildPartB (); builder.buildPartC (); } }; int main () { Director director; ConcreteBuilder1 builder1; director.construct (builder1); auto product1 = builder1. getResult (); product1->show (); ConcreteBuilder2 builder2; director.construct (builder2); auto product2 = builder2. getResult (); product2->show (); return 0 ; }
45.2.4.2 流畅接口变体 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #include <string> #include <vector> class Product {public : std::vector<std::string> parts; void show () const { std::cout << "Product parts: " << std::endl; for (const auto & part : parts) { std::cout << "- " << part << std::endl; } } }; class Builder {public : Builder& addPartA () { product.parts.push_back ("Part A" ); return *this ; } Builder& addPartB () { product.parts.push_back ("Part B" ); return *this ; } Builder& addPartC () { product.parts.push_back ("Part C" ); return *this ; } Product build () { return std::move (product); } private : Product product; }; int main () { Product product = Builder () .addPartA () .addPartB () .addPartC () .build (); product.show (); return 0 ; }
45.2.4.3 应用场景 复杂对象创建 :当对象有很多可选参数时分步构建 :当对象需要分步构建时不可变对象 :当需要创建不可变对象时45.2.5 原型模式(Prototype) 原型模式用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象。
45.2.5.1 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 #include <memory> #include <string> class Prototype {public : virtual ~Prototype () = default ; virtual std::unique_ptr<Prototype> clone () const = 0 ; virtual void show () const = 0 ; }; class ConcretePrototype1 : public Prototype {public : ConcretePrototype1 (const std::string& name) : name (name) {} std::unique_ptr<Prototype> clone () const override { return std::make_unique <ConcretePrototype1>(*this ); } void show () const override { std::cout << "ConcretePrototype1: " << name << std::endl; } private : std::string name; }; class ConcretePrototype2 : public Prototype {public : ConcretePrototype2 (const std::string& name) : name (name) {} std::unique_ptr<Prototype> clone () const override { return std::make_unique <ConcretePrototype2>(*this ); } void show () const override { std::cout << "ConcretePrototype2: " << name << std::endl; } private : std::string name; }; int main () { std::unique_ptr<Prototype> prototype1 = std::make_unique <ConcretePrototype1>("Prototype 1" ); std::unique_ptr<Prototype> prototype2 = std::make_unique <ConcretePrototype2>("Prototype 2" ); auto clone1 = prototype1->clone (); auto clone2 = prototype2->clone (); prototype1->show (); clone1->show (); prototype2->show (); clone2->show (); return 0 ; }
45.2.5.2 深拷贝与浅拷贝 浅拷贝 :只拷贝对象的基本类型成员,对于指针成员只拷贝指针地址深拷贝 :拷贝对象的所有成员,包括指针指向的内容1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Prototype {public : virtual ~Prototype () = default ; virtual std::unique_ptr<Prototype> clone () const = 0 ; virtual void show () const = 0 ; }; class ConcretePrototype : public Prototype {public : ConcretePrototype (int value, const std::string& name) : value (value), name (new std::string (name)) {} ConcretePrototype (const ConcretePrototype& other) : value (other.value), name (new std::string (*other.name)) {} ConcretePrototype (ConcretePrototype&& other) noexcept : value (other.value), name (other.name) { other.name = nullptr ; } ~ConcretePrototype () override { delete name; } std::unique_ptr<Prototype> clone () const override { return std::make_unique <ConcretePrototype>(*this ); } void show () const override { std::cout << "Value: " << value << ", Name: " << *name << std::endl; } private : int value; std::string* name; };
45.2.5.3 应用场景 对象创建成本高 :当对象创建成本较高时,克隆比新建更高效对象结构复杂 :当对象结构复杂,创建过程繁琐时运行时动态创建 :当需要在运行时动态创建对象时45.3 结构型设计模式 45.3.1 适配器模式(Adapter) 适配器模式将一个类的接口转换成客户希望的另一个接口。适配器模式使得那些接口不兼容的类可以一起工作。
45.3.1.1 类适配器(继承) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Target {public : virtual ~Target () = default ; virtual void request () const = 0 ; }; class Adaptee {public : void specificRequest () const { std::cout << "Adaptee's specific request" << std::endl; } }; class ClassAdapter : public Target, private Adaptee {public : void request () const override { specificRequest (); } }; int main () { std::unique_ptr<Target> target = std::make_unique <ClassAdapter>(); target->request (); return 0 ; }
45.3.1.2 对象适配器(组合) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 class Target {public : virtual ~Target () = default ; virtual void request () const = 0 ; }; class Adaptee {public : void specificRequest () const { std::cout << "Adaptee's specific request" << std::endl; } }; class ObjectAdapter : public Target {public : ObjectAdapter (std::unique_ptr<Adaptee> adaptee) : adaptee (std::move (adaptee)) {} void request () const override { adaptee->specificRequest (); } private : std::unique_ptr<Adaptee> adaptee; }; int main () { std::unique_ptr<Target> target = std::make_unique <ObjectAdapter>(std::make_unique <Adaptee>()); target->request (); return 0 ; }
45.3.1.3 应用场景 接口不兼容 :当需要使用一个接口不兼容的类时第三方库集成 :当集成第三方库时,其接口与现有代码不匹配旧系统集成 :当需要集成旧系统时,其接口与新系统不匹配45.3.2 桥接模式(Bridge) 桥接模式将抽象部分与它的实现部分分离,使它们都可以独立地变化。
45.3.2.1 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 #include <memory> #include <string> class Implementor {public : virtual ~Implementor () = default ; virtual void operationImpl () const = 0 ; }; class ConcreteImplementorA : public Implementor {public : void operationImpl () const override { std::cout << "ConcreteImplementorA's operation" << std::endl; } }; class ConcreteImplementorB : public Implementor {public : void operationImpl () const override { std::cout << "ConcreteImplementorB's operation" << std::endl; } }; class Abstraction {public : Abstraction (std::unique_ptr<Implementor> implementor) : implementor (std::move (implementor)) {} virtual ~Abstraction () = default ; virtual void operation () const { implementor->operationImpl (); } protected : std::unique_ptr<Implementor> implementor; }; class RefinedAbstraction : public Abstraction {public : using Abstraction::Abstraction; void operation () const override { std::cout << "RefinedAbstraction's operation: " << std::endl; Abstraction::operation (); } }; int main () { std::unique_ptr<Abstraction> abstractionA = std::make_unique <RefinedAbstraction>(std::make_unique <ConcreteImplementorA>()); abstractionA->operation (); std::unique_ptr<Abstraction> abstractionB = std::make_unique <RefinedAbstraction>(std::make_unique <ConcreteImplementorB>()); abstractionB->operation (); return 0 ; }
45.3.2.2 应用场景 多维度变化 :当一个类有多个维度的变化时平台独立性 :当需要实现平台独立的代码时UI框架 :当UI框架需要与具体实现分离时45.3.3 组合模式(Composite) 组合模式将对象组合成树形结构以表示”部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
45.3.3.1 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 #include <memory> #include <vector> #include <string> class Component {public : virtual ~Component () = default ; virtual void add (std::unique_ptr<Component> component) { } virtual void remove (Component* component) { } virtual Component* getChild (int index) { return nullptr ; } virtual void operation () const = 0 ; }; class Leaf : public Component {public : Leaf (const std::string& name) : name (name) {} void operation () const override { std::cout << "Leaf: " << name << std::endl; } private : std::string name; }; class Composite : public Component {public : Composite (const std::string& name) : name (name) {} void add (std::unique_ptr<Component> component) override { children.push_back (std::move (component)); } void remove (Component* component) override { for (auto it = children.begin (); it != children.end (); ++it) { if (it->get () == component) { children.erase (it); break ; } } } Component* getChild (int index) override { if (index >= 0 && index < children.size ()) { return children[index].get (); } return nullptr ; } void operation () const override { std::cout << "Composite: " << name << std::endl; for (const auto & child : children) { child->operation (); } } private : std::string name; std::vector<std::unique_ptr<Component>> children; }; int main () { auto root = std::make_unique <Composite>("Root" ); root->add (std::make_unique <Leaf>("Leaf 1" )); root->add (std::make_unique <Leaf>("Leaf 2" )); auto branch = std::make_unique <Composite>("Branch" ); branch->add (std::make_unique <Leaf>("Leaf 3" )); branch->add (std::make_unique <Leaf>("Leaf 4" )); root->add (std::move (branch)); root->operation (); return 0 ; }
45.3.3.2 应用场景 树形结构 :当需要处理树形结构时文件系统 :文件和目录的层次结构UI组件 :窗口和控件的层次结构组织架构 :公司和部门的层次结构45.3.4 装饰器模式(Decorator) 装饰器模式动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式比生成子类更为灵活。
45.3.4.1 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 #include <memory> #include <string> class Component {public : virtual ~Component () = default ; virtual std::string operation () const = 0 ; }; class ConcreteComponent : public Component {public : std::string operation () const override { return "ConcreteComponent" ; } }; class Decorator : public Component {public : Decorator (std::unique_ptr<Component> component) : component (std::move (component)) {} std::string operation () const override { return component->operation (); } protected : std::unique_ptr<Component> component; }; class ConcreteDecoratorA : public Decorator {public : using Decorator::Decorator; std::string operation () const override { return "ConcreteDecoratorA(" + Decorator::operation () + ")" ; } }; class ConcreteDecoratorB : public Decorator {public : using Decorator::Decorator; std::string operation () const override { return "ConcreteDecoratorB(" + Decorator::operation () + ")" ; } }; int main () { std::unique_ptr<Component> component = std::make_unique <ConcreteComponent>(); std::cout << "Basic component: " << component->operation () << std::endl; std::unique_ptr<Component> decoratorA = std::make_unique <ConcreteDecoratorA>(std::move (component)); std::cout << "With decorator A: " << decoratorA->operation () << std::endl; std::unique_ptr<Component> decoratorB = std::make_unique <ConcreteDecoratorB>(std::move (decoratorA)); std::cout << "With decorator B: " << decoratorB->operation () << std::endl; return 0 ; }
45.3.4.2 应用场景 动态添加功能 :当需要动态地给对象添加功能时功能组合 :当需要组合多个功能时避免子类爆炸 :当使用继承会导致大量子类时45.3.5 外观模式(Facade) 外观模式为子系统中的一组接口提供一个统一的高层接口,使得子系统更容易使用。
45.3.5.1 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include <memory> class Subsystem1 {public : void operation1 () const { std::cout << "Subsystem1 operation" << std::endl; } }; class Subsystem2 {public : void operation2 () const { std::cout << "Subsystem2 operation" << std::endl; } }; class Subsystem3 {public : void operation3 () const { std::cout << "Subsystem3 operation" << std::endl; } }; class Facade {public : Facade () { subsystem1 = std::make_unique <Subsystem1>(); subsystem2 = std::make_unique <Subsystem2>(); subsystem3 = std::make_unique <Subsystem3>(); } void operation () const { std::cout << "Facade operation:" << std::endl; subsystem1->operation1 (); subsystem2->operation2 (); subsystem3->operation3 (); } private : std::unique_ptr<Subsystem1> subsystem1; std::unique_ptr<Subsystem2> subsystem2; std::unique_ptr<Subsystem3> subsystem3; }; int main () { Facade facade; facade.operation (); return 0 ; }
45.3.5.2 应用场景 复杂子系统 :当子系统非常复杂时API简化 :当需要简化API时分层架构 :当需要在不同层次之间创建接口时45.3.6 享元模式(Flyweight) 享元模式运用共享技术有效地支持大量细粒度的对象。
45.3.6.1 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 #include <memory> #include <string> #include <unordered_map> class Flyweight {public : virtual ~Flyweight () = default ; virtual void operation (const std::string& extrinsicState) const = 0 ; }; class ConcreteFlyweight : public Flyweight {public : ConcreteFlyweight (const std::string& intrinsicState) : intrinsicState (intrinsicState) {} void operation (const std::string& extrinsicState) const override { std::cout << "ConcreteFlyweight: Intrinsic = " << intrinsicState << ", Extrinsic = " << extrinsicState << std::endl; } private : std::string intrinsicState; }; class FlyweightFactory {public : std::shared_ptr<Flyweight> getFlyweight (const std::string& key) { auto it = flyweights.find (key); if (it != flyweights.end ()) { return it->second; } auto flyweight = std::make_shared <ConcreteFlyweight>(key); flyweights[key] = flyweight; return flyweight; } void listFlyweights () const { std::cout << "FlyweightFactory: I have " << flyweights.size () << " flyweights" << std::endl; for (const auto & pair : flyweights) { std::cout << "- " << pair.first << std::endl; } } private : std::unordered_map<std::string, std::shared_ptr<Flyweight>> flyweights; }; int main () { FlyweightFactory factory; auto flyweight1 = factory.getFlyweight ("A" ); auto flyweight2 = factory.getFlyweight ("B" ); auto flyweight3 = factory.getFlyweight ("A" ); flyweight1->operation ("X" ); flyweight2->operation ("Y" ); flyweight3->operation ("Z" ); factory.listFlyweights (); return 0 ; }
45.3.6.2 应用场景 大量细粒度对象 :当需要创建大量细粒度对象时内存限制 :当内存有限制时对象共享 :当对象可以共享内部状态时45.3.7 代理模式(Proxy) 代理模式为其他对象提供一种代理以控制对这个对象的访问。
45.3.7.1 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include <memory> #include <string> class Subject {public : virtual ~Subject () = default ; virtual void request () const = 0 ; }; class RealSubject : public Subject {public : void request () const override { std::cout << "RealSubject: Handling request" << std::endl; } }; class Proxy : public Subject {public : Proxy (std::unique_ptr<Subject> realSubject) : realSubject (std::move (realSubject)) {} void request () const override { if (checkAccess ()) { realSubject->request (); logAccess (); } } private : bool checkAccess () const { std::cout << "Proxy: Checking access prior to requesting a service" << std::endl; return true ; } void logAccess () const { std::cout << "Proxy: Logging the time of request" << std::endl; } std::unique_ptr<Subject> realSubject; }; int main () { std::cout << "Client: Executing the client code with a real subject:" << std::endl; std::unique_ptr<Subject> realSubject = std::make_unique <RealSubject>(); realSubject->request (); std::cout << "\nClient: Executing the same client code with a proxy:" << std::endl; std::unique_ptr<Subject> proxy = std::make_unique <Proxy>(std::make_unique <RealSubject>()); proxy->request (); return 0 ; }
45.3.7.2 代理模式的变体 远程代理 :控制对远程对象的访问虚拟代理 :按需创建开销大的对象保护代理 :控制对对象的访问权限智能引用 :在访问对象时执行额外的操作45.3.7.3 应用场景 远程服务 :当需要访问远程对象时资源密集型对象 :当对象创建成本高时权限控制 :当需要控制访问权限时日志记录 :当需要记录访问日志时45.4 行为型设计模式 45.4.1 观察者模式(Observer) 观察者模式定义了对象之间的一对多依赖关系,使得当一个对象状态发生变化时,所有依赖它的对象都会自动收到通知并更新。
45.4.1.1 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 #include <memory> #include <vector> #include <string> class Subject ;class Observer {public : virtual ~Observer () = default ; virtual void update (const Subject& subject) = 0 ; }; class Subject {public : virtual ~Subject () = default ; void attach (std::shared_ptr<Observer> observer) { observers.push_back (observer); } void detach (std::shared_ptr<Observer> observer) { for (auto it = observers.begin (); it != observers.end (); ++it) { if (it->lock () == observer) { observers.erase (it); break ; } } } void notify () { for (const auto & weakObserver : observers) { if (auto observer = weakObserver.lock ()) { observer->update (*this ); } } } virtual int getState () const = 0 ; virtual void setState (int state) = 0 ; private : std::vector<std::weak_ptr<Observer>> observers; }; class ConcreteSubject : public Subject {public : int getState () const override { return state; } void setState (int state) override { this ->state = state; notify (); } private : int state; }; class ConcreteObserverA : public Observer {public : void update (const Subject& subject) override { state = subject.getState (); std::cout << "ConcreteObserverA: Updated state to " << state << std::endl; } private : int state; }; class ConcreteObserverB : public Observer {public : void update (const Subject& subject) override { state = subject.getState (); std::cout << "ConcreteObserverB: Updated state to " << state << std::endl; } private : int state; }; int main () { std::shared_ptr<Subject> subject = std::make_shared <ConcreteSubject>(); std::shared_ptr<Observer> observerA = std::make_shared <ConcreteObserverA>(); std::shared_ptr<Observer> observerB = std::make_shared <ConcreteObserverB>(); subject->attach (observerA); subject->attach (observerB); std::dynamic_pointer_cast <ConcreteSubject>(subject)->setState (10 ); std::dynamic_pointer_cast <ConcreteSubject>(subject)->setState (20 ); subject->detach (observerA); std::dynamic_pointer_cast <ConcreteSubject>(subject)->setState (30 ); return 0 ; }
45.4.1.2 应用场景 事件处理 :当需要处理事件时模型-视图-控制器 :当使用MVC架构时发布-订阅系统 :当需要实现发布-订阅模式时45.4.2 策略模式(Strategy) 策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户。
45.4.2.1 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 #include <memory> #include <string> class Strategy {public : virtual ~Strategy () = default ; virtual std::string doOperation (const std::string& data) const = 0 ; }; class ConcreteStrategyA : public Strategy {public : std::string doOperation (const std::string& data) const override { std::string result = data; std::reverse (result.begin (), result.end ()); return "ConcreteStrategyA: " + result; } }; class ConcreteStrategyB : public Strategy {public : std::string doOperation (const std::string& data) const override { std::string result = data; for (char & c : result) { if (std::isalpha (c)) { c = std::toupper (c); } } return "ConcreteStrategyB: " + result; } }; class Context {public : Context (std::unique_ptr<Strategy> strategy) : strategy (std::move (strategy)) {} void setStrategy (std::unique_ptr<Strategy> strategy) { this ->strategy = std::move (strategy); } std::string executeStrategy (const std::string& data) const { return strategy->doOperation (data); } private : std::unique_ptr<Strategy> strategy; }; int main () { Context context (std::make_unique<ConcreteStrategyA>()) ; std::cout << context.executeStrategy ("Hello World" ) << std::endl; context.setStrategy (std::make_unique <ConcreteStrategyB>()); std::cout << context.executeStrategy ("Hello World" ) << std::endl; return 0 ; }
45.4.2.2 使用lambda表达式简化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #include <functional> #include <string> class Context {public : using Strategy = std::function<std::string (const std::string&)>; Context (Strategy strategy) : strategy (std::move (strategy)) {} void setStrategy (Strategy strategy) { this ->strategy = std::move (strategy); } std::string executeStrategy (const std::string& data) const { return strategy (data); } private : Strategy strategy; }; int main () { Context context ([](const std::string& data) { std::string result = data; std::reverse(result.begin(), result.end()); return "Reversed: " + result; }) ; std::cout << context.executeStrategy ("Hello World" ) << std::endl; context.setStrategy ([](const std::string& data) { std::string result = data; for (char & c : result) { if (std::isalpha (c)) { c = std::toupper (c); } } return "Uppercase: " + result; }); std::cout << context.executeStrategy ("Hello World" ) << std::endl; return 0 ; }
45.4.2.3 应用场景 算法选择 :当需要在运行时选择算法时排序策略 :当需要不同的排序算法时验证策略 :当需要不同的验证规则时支付方式 :当需要不同的支付方式时45.4.3 命令模式(Command) 命令模式将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
45.4.3.1 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 #include <memory> #include <vector> class Receiver {public : void action () const { std::cout << "Receiver: Action performed" << std::endl; } void undoAction () const { std::cout << "Receiver: Action undone" << std::endl; } }; class Command {public : virtual ~Command () = default ; virtual void execute () = 0 ; virtual void undo () = 0 ; }; class ConcreteCommand : public Command {public : ConcreteCommand (std::shared_ptr<Receiver> receiver) : receiver (receiver) {} void execute () override { receiver->action (); } void undo () override { receiver->undoAction (); } private : std::shared_ptr<Receiver> receiver; }; class NoCommand : public Command {public : void execute () override { } void undo () override { } }; class Invoker {public : void setCommand (std::unique_ptr<Command> command) { this ->command = std::move (command); } void executeCommand () { command->execute (); history.push_back (command.get ()); } void undoCommand () { if (!history.empty ()) { history.back ()->undo (); history.pop_back (); } } private : std::unique_ptr<Command> command; std::vector<Command*> history; }; int main () { std::shared_ptr<Receiver> receiver = std::make_shared <Receiver>(); std::unique_ptr<Command> command = std::make_unique <ConcreteCommand>(receiver); Invoker invoker; invoker.setCommand (std::move (command)); invoker.executeCommand (); invoker.undoCommand (); return 0 ; }
45.4.3.2 应用场景 菜单操作 :当需要实现菜单操作时撤销/重做 :当需要支持撤销和重做操作时事务处理 :当需要实现事务时队列请求 :当需要队列处理请求时45.4.4 迭代器模式(Iterator) 迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
45.4.4.1 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 #include <memory> #include <vector> class Iterator ;class ConcreteIterator ;class Aggregate {public : virtual ~Aggregate () = default ; virtual std::unique_ptr<Iterator> createIterator () = 0 ; virtual int size () const = 0 ; virtual int get (int index) const = 0 ; }; class Iterator {public : virtual ~Iterator () = default ; virtual bool hasNext () const = 0 ; virtual int next () = 0 ; }; class ConcreteAggregate : public Aggregate {public : void add (int value) { items.push_back (value); } std::unique_ptr<Iterator> createIterator () override { return std::make_unique <ConcreteIterator>(this ); } int size () const override { return items.size (); } int get (int index) const override { return items[index]; } private : std::vector<int > items; }; class ConcreteIterator : public Iterator {public : ConcreteIterator (ConcreteAggregate* aggregate) : aggregate (aggregate), index (0 ) {} bool hasNext () const override { return index < aggregate->size (); } int next () override { return aggregate->get (index++); } private : ConcreteAggregate* aggregate; int index; }; int main () { std::unique_ptr<ConcreteAggregate> aggregate = std::make_unique <ConcreteAggregate>(); aggregate->add (1 ); aggregate->add (2 ); aggregate->add (3 ); aggregate->add (4 ); aggregate->add (5 ); std::unique_ptr<Iterator> iterator = aggregate->createIterator (); std::cout << "Iterating over aggregate: " << std::endl; while (iterator->hasNext ()) { std::cout << iterator->next () << " " << std::endl; } return 0 ; }
45.4.4.2 使用STL迭代器 现代C++中,STL已经提供了丰富的迭代器实现,我们可以直接使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <vector> #include <list> #include <map> #include <iostream> int main () { std::vector<int > vec = {1 , 2 , 3 , 4 , 5 }; std::cout << "Vector elements: " << std::endl; for (auto it = vec.begin (); it != vec.end (); ++it) { std::cout << *it << " " << std::endl; } std::cout << "Vector elements (range for): " << std::endl; for (int value : vec) { std::cout << value << " " << std::endl; } return 0 ; }
45.4.4.3 应用场景 集合遍历 :当需要遍历集合而不暴露其内部结构时多态遍历 :当需要统一遍历不同类型的集合时只读遍历 :当需要提供只读访问时45.4.5 状态模式(State) 状态模式允许对象在内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
45.4.5.1 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 #include <memory> class Context ;class State {public : virtual ~State () = default ; virtual void handle (Context* context) = 0 ; }; class ConcreteStateA : public State {public : void handle (Context* context) override ; }; class ConcreteStateB : public State {public : void handle (Context* context) override ; }; class Context {public : Context (std::unique_ptr<State> state) : state (std::move (state)) {} void setState (std::unique_ptr<State> state) { this ->state = std::move (state); } void request () { state->handle (this ); } private : std::unique_ptr<State> state; }; void ConcreteStateA::handle (Context* context) { std::cout << "ConcreteStateA: Handling request" << std::endl; context->setState (std::make_unique <ConcreteStateB>()); } void ConcreteStateB::handle (Context* context) { std::cout << "ConcreteStateB: Handling request" << std::endl; context->setState (std::make_unique <ConcreteStateA>()); } int main () { Context context (std::make_unique<ConcreteStateA>()) ; context.request (); context.request (); context.request (); return 0 ; }
45.4.5.2 应用场景 状态转换 :当对象有多个状态,且状态转换有明确规则时有限状态机 :当需要实现有限状态机时行为变化 :当对象的行为依赖于其状态时45.4.6 模板方法模式(Template Method) 模板方法模式定义了一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
45.4.6.1 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 #include <iostream> class AbstractClass {public : virtual ~AbstractClass () = default ; void templateMethod () { primitiveOperation1 (); primitiveOperation2 (); hook (); } protected : virtual void primitiveOperation1 () = 0 ; virtual void primitiveOperation2 () = 0 ; virtual void hook () { std::cout << "AbstractClass: Default hook implementation" << std::endl; } }; class ConcreteClassA : public AbstractClass {protected : void primitiveOperation1 () override { std::cout << "ConcreteClassA: primitiveOperation1" << std::endl; } void primitiveOperation2 () override { std::cout << "ConcreteClassA: primitiveOperation2" << std::endl; } }; class ConcreteClassB : public AbstractClass {protected : void primitiveOperation1 () override { std::cout << "ConcreteClassB: primitiveOperation1" << std::endl; } void primitiveOperation2 () override { std::cout << "ConcreteClassB: primitiveOperation2" << std::endl; } void hook () override { std::cout << "ConcreteClassB: Overridden hook implementation" << std::endl; } }; int main () { std::cout << "Client: Testing ConcreteClassA" << std::endl; AbstractClass* concreteA = new ConcreteClassA (); concreteA->templateMethod (); delete concreteA; std::cout << "\nClient: Testing ConcreteClassB" << std::endl; AbstractClass* concreteB = new ConcreteClassB (); concreteB->templateMethod (); delete concreteB; return 0 ; }
45.4.6.2 应用场景 算法骨架 :当需要定义算法骨架,而将具体实现延迟到子类时代码复用 :当多个子类共享相同的算法结构时控制子类扩展 :当需要控制子类的扩展点时45.4.7 访问者模式(Visitor) 访问者模式表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
45.4.7.1 现代C++实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 #include <memory> #include <vector> class ConcreteElementA ;class ConcreteElementB ;class Visitor {public : virtual ~Visitor () = default ; virtual void visit (ConcreteElementA* element) = 0 ; virtual void visit (ConcreteElementB* element) = 0 ; }; class Element {public : virtual ~Element () = default ; virtual void accept (Visitor* visitor) = 0 ; }; class ConcreteElementA : public Element {public : void accept (Visitor* visitor) override { visitor->visit (this ); } void operationA () { std::cout << "ConcreteElementA: operationA" << std::endl; } }; class ConcreteElementB : public Element {public : void accept (Visitor* visitor) override { visitor->visit (this ); } void operationB () { std::cout << "ConcreteElementB: operationB" << std::endl; } }; class ConcreteVisitorA : public Visitor {public : void visit (ConcreteElementA* element) override { std::cout << "ConcreteVisitorA: visiting ConcreteElementA" << std::endl; element->operationA (); } void visit (ConcreteElementB* element) override { std::cout << "ConcreteVisitorA: visiting ConcreteElementB" << std::endl; element->operationB (); } }; class ConcreteVisitorB : public Visitor {public : void visit (ConcreteElementA* element) override { std::cout << "ConcreteVisitorB: visiting ConcreteElementA" << std::endl; element->operationA (); } void visit (ConcreteElementB* element) override { std::cout << "ConcreteVisitorB: visiting ConcreteElementB" << std::endl; element->operationB (); } }; class ObjectStructure {public : void addElement (std::unique_ptr<Element> element) { elements.push_back (std::move (element)); } void accept (Visitor* visitor) { for (const auto & element : elements) { element->accept (visitor); } } private : std::vector<std::unique_ptr<Element>> elements; }; int main () { ObjectStructure objectStructure; objectStructure.addElement (std::make_unique <ConcreteElementA>()); objectStructure.addElement (std::make_unique <ConcreteElementB>()); std::cout << "Using ConcreteVisitorA:" << std::endl; ConcreteVisitorA visitorA; objectStructure.accept (&visitorA); std::cout << "\nUsing ConcreteVisitorB:" << std::endl; ConcreteVisitorB visitorB; objectStructure.accept (&visitorB); return 0 ; }
45.4.7.2 应用场景 复杂对象结构 :当对象结构复杂,且需要对其中的元素执行不同操作时新增操作 :当需要为对象结构添加新操作,而不修改元素类时分离算法 :当需要将算法与对象结构分离时45.5 现代C++中的设计模式 45.5.1 智能指针与设计模式 现代C++的智能指针(std::unique_ptr、std::shared_ptr、std::weak_ptr)为设计模式的实现提供了更安全、更简洁的方式:
单例模式 :使用std::unique_ptr或静态局部变量管理实例工厂方法 :返回std::unique_ptr或std::shared_ptr抽象工厂 :返回智能指针建造者模式 :返回std::unique_ptr原型模式 :使用std::unique_ptr或std::shared_ptr适配器模式 :使用智能指针管理被适配者桥接模式 :使用智能指针管理实现组合模式 :使用std::unique_ptr管理子组件装饰器模式 :使用std::unique_ptr管理被装饰对象代理模式 :使用std::unique_ptr管理真实对象观察者模式 :使用std::weak_ptr避免循环引用命令模式 :使用智能指针管理命令和接收者45.5.2 Lambda表达式与设计模式 Lambda表达式为设计模式的实现提供了更简洁的方式:
策略模式 :使用lambda作为策略命令模式 :使用lambda作为命令观察者模式 :使用lambda作为回调访问者模式 :使用lambda作为访问者45.5.3 移动语义与设计模式 移动语义(C++11引入)提高了设计模式实现的性能:
原型模式 :使用移动构造函数提高克隆性能建造者模式 :使用移动语义返回产品工厂方法 :使用移动语义返回产品45.5.4 模板与设计模式 模板为设计模式的实现提供了更灵活的方式:
策略模式 :使用模板参数指定策略访问者模式 :使用模板实现通用访问者工厂方法 :使用模板创建不同类型的对象45.6 设计模式的最佳实践 45.6.1 设计模式的选择 理解问题 :首先要理解问题的本质选择合适的模式 :根据问题选择最适合的设计模式考虑上下文 :考虑项目的具体上下文和约束不要过度设计 :不要为了使用设计模式而使用设计模式45.6.2 设计模式的实现 45.6.3 设计模式的演化 设计模式不是一成不变的,它们会随着语言和技术的发展而演化:
从传统C++到现代C++ :使用智能指针、lambda表达式等现代特性从面向对象到函数式 :结合函数式编程思想从静态到动态 :使用运行时多态和反射从单一模式到模式组合 :组合使用多个设计模式45.7 设计模式的实际应用 45.7.1 框架中的设计模式 许多流行的C++框架都使用了设计模式:
Qt :使用了观察者模式(信号槽)、工厂方法、单例模式等Boost :使用了各种设计模式,如智能指针(代理模式的变体)、策略模式等STL :使用了迭代器模式、策略模式、适配器模式等45.7.2 企业应用中的设计模式 MVC :模型-视图-控制器模式,用于UI开发DAO :数据访问对象模式,用于数据库访问Service Locator :服务定位器模式,用于依赖管理Dependency Injection :依赖注入模式,用于控制反转45.7.3 游戏开发中的设计模式 游戏循环 :模板方法模式的变体实体组件系统 :组合模式的变体状态管理 :状态模式AI行为 :策略模式、状态模式、行为树45.8 小结 本章介绍了现代C++中的设计模式,包括:
设计模式概述 :设计模式的概念、分类和重要性创建型设计模式 :单例模式、工厂方法、抽象工厂、建造者模式、原型模式结构型设计模式 :适配器模式、桥接模式、组合模式、装饰器模式、外观模式、享元模式、代理模式行为型设计模式 :观察者模式、策略模式、命令模式、迭代器模式、状态模式、模板方法模式、访问者模式现代C++中的设计模式 :智能指针、lambda表达式、移动语义、模板与设计模式的结合设计模式的最佳实践 :设计模式的选择、实现、演化设计模式的实际应用 :框架、企业应用、游戏开发中的设计模式设计模式是C++编程中的重要工具,它们提供了经过验证的解决方案,可以帮助我们编写更清晰、更可维护、更可扩展的代码。通过学习和应用设计模式,我们可以提高自己的编程水平,更好地解决复杂的软件设计问题。
同时,我们也应该认识到,设计模式不是银弹,它们只是工具,需要根据具体情况合理使用。在实际开发中,我们应该根据问题的本质,选择合适的设计模式,并结合现代C++的特性,创造出既优雅又高效的解决方案。