设计模式通常被分为三大类:创建型模式、结构型模式、行为型模式。每一类中都有若干种具体的模式。根据经典的《设计模式:可复用面向对象软件的基础》(《Design Patterns: Elements of Reusable Object-Oriented Software》)一书,设计模式的总数是 23 种,这些模式被广泛应用于软件开发中。
下面是 23 种设计模式的分类和名称:
1. 创建型模式 (Creational Patterns)
这些模式关注对象的创建,尤其是如何实例化对象以及如何避免直接使用构造函数。
-
单例模式 (Singleton Pattern)
-
工厂方法模式 (Factory Method Pattern)
-
抽象工厂模式 (Abstract Factory Pattern)
-
建造者模式 (Builder Pattern)
-
原型模式 (Prototype Pattern)
2. 结构型模式 (Structural Patterns)
这些模式关注如何组合类和对象以形成更大的结构。
-
适配器模式 (Adapter Pattern)
-
桥接模式 (Bridge Pattern)
-
组合模式 (Composite Pattern)
-
装饰器模式 (Decorator Pattern)
-
外观模式 (Facade Pattern)
-
享元模式 (Flyweight Pattern)
-
代理模式 (Proxy Pattern)
3. 行为型模式 (Behavioral Patterns)
这些模式关注对象之间的交互和职责分配。
-
责任链模式 (Chain of Responsibility Pattern)
-
命令模式 (Command Pattern)
-
解释器模式 (Interpreter Pattern)
-
迭代器模式 (Iterator Pattern)
-
中介者模式 (Mediator Pattern)
-
备忘录模式 (Memento Pattern)
-
观察者模式 (Observer Pattern)
-
状态模式 (State Pattern)
-
策略模式 (Strategy Pattern)
-
模板方法模式 (Template Method Pattern)
-
访问者模式 (Visitor Pattern)
1. 创建型模式 (Creational Patterns)
这些模式主要关注对象的创建机制,确保系统在创建对象时保持灵活性和可扩展性。
1.1 单例模式 (Singleton Pattern)
-
定义:保证一个类只有一个实例,并提供全局访问点。
-
结构:包含一个私有的静态实例,以及一个公共的静态方法用于获取该实例。
-
应用场景:用于控制资源的共享,比如日志管理器、数据库连接池等。
-
示例:
class Singleton { private: static Singleton* instance; Singleton() {} public: static Singleton* getInstance() { if (!instance) instance = new Singleton(); return instance; } }; Singleton* Singleton::instance = nullptr;
1.2 工厂方法模式 (Factory Method Pattern)
-
定义:定义一个创建对象的接口,让子类决定实例化哪个类。
-
结构:一个抽象类声明工厂方法,子类实现该方法。
-
应用场景:当系统需要创建的对象种类较多,且每个对象的创建逻辑较为复杂时。
-
示例:
class Product { public: virtual void operation() = 0; }; class ConcreteProductA : public Product { public: void operation() override { std::cout << "Operation A" << std::endl; } }; class Creator { public: virtual Product* createProduct() = 0; }; class ConcreteCreatorA : public Creator { public: Product* createProduct() override { return new ConcreteProductA(); } };
1.3 抽象工厂模式 (Abstract Factory Pattern)
-
定义:提供一个接口,用于创建相关或依赖对象的家族,而不需要指定具体类。
-
结构:包含多个工厂,每个工厂负责创建一类产品。
-
应用场景:当产品需要遵循相同的接口或结构,并且产品的种类较多时。
-
示例:
-
class AbstractProductA { public: virtual void operationA() = 0; }; class AbstractProductB { public: virtual void operationB() = 0; }; class ConcreteProductA1 : public AbstractProductA { public: void operationA() override { std::cout << "Product A1 Operation" << std::endl; } }; class ConcreteProductB1 : public AbstractProductB { public: void operationB() override { std::cout << "Product B1 Operation" << std::endl; } }; class AbstractFactory { public: virtual AbstractProductA* createProductA() = 0; virtual AbstractProductB* createProductB() = 0; }; class ConcreteFactory1 : public AbstractFactory { public: AbstractProductA* createProductA() override { return new ConcreteProductA1(); } AbstractProductB* createProductB() override { return new ConcreteProductB1(); } };
1.4 建造者模式 (Builder Pattern)
-
定义:将一个复杂对象的构建过程抽象化,使得同样的构建过程可以创建不同的表示。
-
结构:包括一个指挥者(Director)类,负责构建产品;一个建造者(Builder)类,负责构建各个部分。
-
应用场景:用于构建复杂的对象时,能够灵活地选择不同的构建方式。
-
示例:
-
class Product { public: void addPart(const std::string& part) { parts.push_back(part); } void show() { for (const auto& part : parts) { std::cout << part << std::endl; } } private: std::vector<std::string> parts; }; class Builder { public: virtual void buildPartA() = 0; virtual void buildPartB() = 0; virtual Product* getResult() = 0; }; class ConcreteBuilder : public Builder { private: Product* product; public: ConcreteBuilder() : product(new Product()) {} void buildPartA() override { product->addPart("Part A"); } void buildPartB() override { product->addPart("Part B"); } Product* getResult() override { return product; } }; class Director { private: Builder* builder; public: Director(Builder* builder) : builder(builder) {} void construct() { builder->buildPartA(); builder->buildPartB(); } };
1.5 原型模式 (Prototype Pattern)
-
定义:通过复制现有的实例来创建新对象,而不是通过新建对象。
-
结构:包括一个原型接口和具体的原型类。
-
应用场景:当对象的创建成本较高,且对象的种类繁多时。
-
示例:
-
class Prototype { public: virtual Prototype* clone() = 0; }; class ConcretePrototype : public Prototype { private: int value; public: ConcretePrototype(int value) : value(value) {} Prototype* clone() override { return new ConcretePrototype(value); } int getValue() const { return value; } };
2. 结构型模式 (Structural Patterns)
这些模式关注如何组织类和对象,以形成较为复杂的结构。
2.1 适配器模式 (Adapter Pattern)
-
定义:将一个类的接口转换成客户端希望的另一个接口,使得原本不兼容的类能够一起工作。
-
结构:包含目标接口、适配器类和被适配的类。
-
应用场景:当需要将现有类的接口转换为符合系统要求的接口时。
-
示例:
class Target { public: virtual void request() = 0; }; class Adaptee { public: void specificRequest() { std::cout << "Specific request" << std::endl; } }; class Adapter : public Target { private: Adaptee* adaptee; public: Adapter(Adaptee* adaptee) : adaptee(adaptee) {} void request() override { adaptee->specificRequest(); } };
2.2 桥接模式 (Bridge Pattern)
2.4 装饰器模式 (Decorator Pattern)
2.5 外观模式 (Facade Pattern)
2.6 享元模式 (Flyweight Pattern)
2.7 代理模式 (Proxy Pattern)
-
定义:将抽象部分与实现部分分离,使它们可以独立变化。
-
结构:包含抽象类、实现类和两个之间的桥接类。
-
应用场景:当需要在不同的维度上进行扩展时,比如设备与接口的组合。
-
示例:
-
class Implementor { public: virtual void operationImpl() = 0; }; class ConcreteImplementorA : public Implementor { public: void operationImpl() override { std::cout << "ConcreteImplementorA operation" << std::endl; } }; class Abstract { protected: Implementor* implementor; public: Abstract(Implementor* implementor) : implementor(implementor) {} virtual void operation() = 0; }; class RefinedAbstraction : public Abstract { public: RefinedAbstraction(Implementor* implementor) : Abstract(implementor) {} void operation() override { implementor->operationImpl(); } };
2.3 组合模式 (Composite Pattern)
-
定义:将对象组合成树形结构以表示部分-整体的层次结构,使得客户端可以统一对待单个对象和组合对象。
-
结构:包含一个组件接口,一个叶节点类和一个容器类(通常是组合类)。
-
应用场景:当你需要表示“部分”和“整体”之间的层次结构时,例如文件系统、图形界面。
-
示例:
-
class Component { public: virtual void operation() = 0; }; class Leaf : public Component { public: void operation() override { std::cout << "Leaf operation" << std::endl; } }; class Composite : public Component { private: std::vector<Component*> children; public: void add(Component* component) { children.push_back(component); } void operation() override { for (auto& child : children) { child->operation(); } } };
-
定义:动态地给对象添加额外的功能,而不影响其他对象。
-
结构:包含一个组件接口和一个装饰器类,它通过委托将行为传递给原始对象。
-
应用场景:需要扩展对象的功能时,但又不想通过继承的方式来增加新功能。
-
class Component { public: virtual void operation() = 0; }; class ConcreteComponent : public Component { public: void operation() override { std::cout << "ConcreteComponent operation" << std::endl; } }; class Decorator : public Component { protected: Component* component; public: Decorator(Component* component) : component(component) {} void operation() override { component->operation(); } }; class ConcreteDecoratorA : public Decorator { public: ConcreteDecoratorA(Component* component) : Decorator(component) {} void operation() override { Decorator::operation(); std::cout << "ConcreteDecoratorA added behavior" << std::endl; } };
-
定义:为子系统中的一组接口提供一个统一的高层接口,简化了系统的复杂性。
-
结构:包含一个外观类(Facade),它封装了对多个子系统的调用。
-
应用场景:当你需要向客户端提供一个简单的接口来访问复杂的子系统时。
-
示例:
class SubsystemA { public: void operationA() { std::cout << "SubsystemA operation" << std::endl; } }; class SubsystemB { public: void operationB() { std::cout << "SubsystemB operation" << std::endl; } }; class Facade { private: SubsystemA* subsystemA; SubsystemB* subsystemB; public: Facade() : subsystemA(new SubsystemA()), subsystemB(new SubsystemB()) {} void simplifiedOperation() { subsystemA->operationA(); subsystemB->operationB(); } };
-
定义:通过共享对象来减少内存占用,将对象分为可共享和不可共享的部分,避免重复创建相同的对象。
-
结构:包含享元接口、具体享元类、享元工厂类等。
-
应用场景:当对象数量较多且对象之间的相似度较高时,尤其是内存和性能受限时。
-
示例:
-
class Flyweight { public: virtual void operation() = 0; }; class ConcreteFlyweight : public Flyweight { private: int intrinsicState; public: ConcreteFlyweight(int state) : intrinsicState(state) {} void operation() override { std::cout << "Flyweight with state " << intrinsicState << std::endl; } }; class FlyweightFactory { private: std::unordered_map<int, Flyweight*> flyweights; public: Flyweight* getFlyweight(int state) { if (flyweights.find(state) == flyweights.end()) { flyweights[state] = new ConcreteFlyweight(state); } return flyweights[state]; } };
-
定义:为其他对象提供一种代理以控制对这个对象的访问。
-
结构:包含真实对象、代理类和一个客户端访问代理类。
-
应用场景:需要控制对对象的访问,如延迟加载、权限控制等。
-
示例:
class RealSubject { public: void request() { std::cout << "RealSubject request" << std::endl; } }; class Proxy { private: RealSubject* realSubject; public: Proxy() : realSubject(new RealSubject()) {} void request() { std::cout << "Proxy forwarding request" << std::endl; realSubject->request(); } };
3. 行为型模式 (Behavioral Patterns)
这些模式关注对象之间的交互和责任分配。
3.1 责任链模式 (Chain of Responsibility Pattern)
3.4 迭代器模式 (Iterator Pattern)
-
定义:通过多个处理者对象形成链条,沿着链条传递请求,直到请求被处理为止。
-
结构:包含一个处理者类,多个处理者形成链式结构。
-
应用场景:当有多个对象可以处理请求时,可以避免请求的发送者与处理者之间的耦合。
-
示例:
-
class Command { public: virtual void execute() = 0; }; class Receiver { public: void action() { std::cout << "Receiver action" << std::endl; } }; class ConcreteCommand : public Command { private: Receiver* receiver; public: ConcreteCommand(Receiver* receiver) : receiver(receiver) {} void execute() override { receiver->action(); } }; class Invoker { private: Command* command; public: void setCommand(Command* command) { this->command = command; } void invoke() { command->execute(); } };
3.3 解释器模式 (Interpreter Pattern)
-
定义:为语言中的每个符号创建一个解释器,并通过解析文法表达式来解释整个语言。
-
结构:包含一个抽象表达式类,多个终结符表达式类和上下文类。
-
class Expression { public: virtual bool interpret(const std::string& context) = 0; }; class TerminalExpression : public Expression { public: bool interpret(const std::string& context) override { return context == "Hello"; } }; class OrExpression : public Expression { private: Expression* expr1; Expression* expr2; public: OrExpression(Expression* expr1, Expression* expr2) : expr1(expr1), expr2(expr2) {} bool interpret(const std::string& context) override { return expr1->interpret(context) || expr2->interpret(context); } };
-
定义:提供一种顺序访问集合元素的方法,而不暴露集合的内部表示。
-
结构
class Iterator { public: virtual bool hasNext() = 0; virtual int next() = 0; }; class ConcreteIterator : public Iterator { private: std::vector<int> collection; size_t index = 0; public: ConcreteIterator(const std::vector<int>& collection) : collection(collection) {} bool hasNext() override { return index < collection.size(); } int next() override { return collection[index++]; } };