本文将介绍编程中的23种设计模式,用C++语言编写。
前言
设计模式是软件设计中常用的解决方案,分为三大类:创建型模式、结构型模式和行为型模式。以下是23种设计模式的简要介绍和C++代码示例。
正文
创建型模式
创建型模式关注对象的创建过程,旨在通过隐藏创建逻辑来提高代码的灵活性和可维护性。单例模式确保一个类只有一个实例,适用于需要全局访问的资源,如配置文件或数据库连接池。工厂方法模式和抽象工厂模式通过定义创建对象的接口,允许子类或具体工厂决定实例化的具体类,适用于需要灵活创建对象的场景。建造者模式将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。原型模式通过复制现有实例来创建新对象,适用于需要大量相似对象的场景。
1.单例模式(Singleton)
确保一个类只有一个实例,并提供一个全局访问点。
class Singleton {
public:
static Singleton& getInstance() {
static Singleton instance;
return instance;
}
private:
Singleton() {}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
2.工厂方法模式(Factory Method)
定义一个创建对象的接口,但由子类决定实例化哪一个类。
class Product {
public:
virtual void use() = 0;
};
class ConcreteProduct : public Product {
public:
void use() override {
// Implementation
}
};
class Creator {
public:
virtual Product* factoryMethod() = 0;
};
class ConcreteCreator : public Creator {
public:
Product* factoryMethod() override {
return new ConcreteProduct();
}
};
3.抽象工厂模式(Abstract Factory)
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
class AbstractProductA {
public:
virtual void use() = 0;
};
class AbstractProductB {
public:
virtual void use() = 0;
};
class ConcreteProductA1 : public AbstractProductA {
public:
void use() override {
// Implementation
}
};
class ConcreteProductB1 : public AbstractProductB {
public:
void use() override {
// Implementation
}
};
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();
}
};
4.建造者模式(Builder)
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
class Product {
public:
void setPartA(const std::string& part) {
partA = part;
}
void setPartB(const std::string& part) {
partB = part;
}
private:
std::string partA;
std::string partB;
};
class Builder {
public:
virtual void buildPartA() = 0;
virtual void buildPartB() = 0;
virtual Product* getResult() = 0;
};
class ConcreteBuilder : public Builder {
public:
ConcreteBuilder() {
product = new Product();
}
void buildPartA() override {
product->setPartA("PartA");
}
void buildPartB() override {
product->setPartB("PartB");
}
Product* getResult() override {
return product;
}
private:
Product* product;
};
class Director {
public:
void setBuilder(Builder* b) {
builder = b;
}
void construct() {
builder->buildPartA();
builder->buildPartB();
}
private:
Builder* builder;
};
5.原型模式(Prototype)
用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
class Prototype {
public:
virtual Prototype* clone() = 0;
};
class ConcretePrototype : public Prototype {
public:
ConcretePrototype(int value) : value(value) {}
Prototype* clone() override {
return new ConcretePrototype(*this);
}
private:
int value;
};
结构型模式
结构型模式关注类和对象的组合,旨在通过继承和组合来实现更大的灵活性和可扩展性。适配器模式将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。桥接模式将抽象部分与其实现部分分离,使它们可以独立变化。组合模式将对象组合成树形结构,以表示“部分-整体”的层次结构,适用于需要处理树形结构的场景。装饰模式动态地给对象添加职责,比生成子类更灵活。外观模式为子系统提供一个一致的接口,简化其使用。享元模式通过共享技术有效地支持大量细粒度对象,适用于需要大量相似对象的场景。代理模式为其他对象提供一种代理以控制对这个对象的访问,适用于需要控制访问的场景。
6.适配器模式(Adapter)
将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
class Target {
public:
virtual void request() = 0;
};
class Adaptee {
public:
void specificRequest() {
// Implementation
}
};
class Adapter : public Target {
public:
Adapter(Adaptee* adaptee) : adaptee(adaptee) {}
void request() override {
adaptee->specificRequest();
}
private:
Adaptee* adaptee;
};
7.桥接模式(Bridge)
将抽象部分与它的实现部分分离,使它们都可以独立地变化。
class Implementor {
public:
virtual void operationImpl() = 0;
};
class ConcreteImplementorA : public Implementor {
public:
void operationImpl() override {
// Implementation
}
};
class Abstraction {
public:
Abstraction(Implementor* impl) : impl(impl) {}
virtual void operation() {
impl->operationImpl();
}
private:
Implementor* impl;
};
8.组合模式(Composite)
将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
class Component {
public:
virtual void operation() = 0;
};
class Leaf : public Component {
public:
void operation() override {
// Implementation
}
};
class Composite : public Component {
public:
void add(Component* component) {
children.push_back(component);
}
void operation() override {
for (auto child : children) {
child->operation();
}
}
private:
std::vector<Component*> children;
};
9.装饰模式(Decorator)
动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
class Component {
public:
virtual void operation() = 0;
};
class ConcreteComponent : public Component {
public:
void operation() override {
// Implementation
}
};
class Decorator : public Component {
public:
Decorator(Component* component) : component(component) {}
void operation() override {
component->operation();
}
private:
Component* component;
};
10.外观模式(Facade)
为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
class Subsystem1 {
public:
void operation1() {
// Implementation
}
};
class Subsystem2 {
public:
void operation2() {
// Implementation
}
};
class Facade {
public:
void operation() {
subsystem1.operation1();
subsystem2.operation2();
}
private:
Subsystem1 subsystem1;
Subsystem2 subsystem2;
};
11.享元模式(Flyweight)
运用共享技术有效地支持大量细粒度的对象。
class Flyweight {
public:
virtual void operation() = 0;
};
class ConcreteFlyweight : public Flyweight {
public:
void operation() override {
// Implementation
}
};
class FlyweightFactory {
public:
Flyweight* getFlyweight(const std::string& key) {
if (flyweights.find(key) == flyweights.end()) {
flyweights[key] = new ConcreteFlyweight();
}
return flyweights[key];
}
private:
std::unordered_map<std::string, Flyweight*> flyweights;
};
12.代理模式(Proxy)
为其他对象提供一种代理以控制对这个对象的访问。
class Subject {
public:
virtual void request() = 0;
};
class RealSubject : public Subject {
public:
void request() override {
// Implementation
}
};
class Proxy : public Subject {
public:
Proxy(RealSubject* realSubject) : realSubject(realSubject) {}
void request() override {
realSubject->request();
}
private:
RealSubject* realSubject;
};
行为型模式
行为型模式关注对象之间的通信,旨在通过定义对象之间的交互来提高系统的灵活性和可维护性。责任链模式使多个对象都有机会处理请求,避免请求的发送者和接收者之间的耦合。命令模式将请求封装成对象,使得不同的请求可以参数化。解释器模式定义语言的文法表示,并使用解释器来解释语言中的句子。迭代器模式提供一种方法顺序访问聚合对象中的各个元素,而不暴露其内部表示。中介者模式用一个中介对象来封装对象的交互,使其耦合松散。备忘录模式在不破坏封装性的前提下捕获对象的内部状态,并在对象之外保存这个状态。观察者模式定义对象间的一对多依赖关系,使得一个对象状态改变时,所有依赖对象都会自动更新。状态模式允许对象在内部状态改变时改变其行为。策略模式定义一系列算法,并使它们可互相替换。模板方法模式定义操作中的算法骨架,将一些步骤延迟到子类中。访问者模式封装作用于某种数据结构中各元素的操作,使得在不改变数据结构的前提下定义新的操作。
13.责任链模式(Chain of Responsibility)
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
class Handler {
public:
virtual void setNext(Handler* next) {
this->next = next;
}
virtual void handleRequest(int request) {
if (next) {
next->handleRequest(request);
}
}
private:
Handler* next = nullptr;
};
class ConcreteHandler1 : public Handler {
public:
void handleRequest(int request) override {
if (request < 10) {
// Handle request
} else {
Handler::handleRequest(request);
}
}
};
class ConcreteHandler2 : public Handler {
public:
void handleRequest(int request) override {
if (request >= 10) {
// Handle request
} else {
Handler::handleRequest(request);
}
}
};
14.命令模式(Command)
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。
class Command {
public:
virtual void execute() = 0;
};
class ConcreteCommand : public Command {
public:
ConcreteCommand(Receiver* receiver) : receiver(receiver) {}
void execute() override {
receiver->action();
}
private:
Receiver* receiver;
};
class Invoker {
public:
void setCommand(Command* command) {
this->command = command;
}
void executeCommand() {
command->execute();
}
private:
Command* command;
};
15.解释器模式(Interpreter)
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
class AbstractExpression {
public:
virtual void interpret(Context& context) = 0;
};
class TerminalExpression : public AbstractExpression {
public:
void interpret(Context& context) override {
// Implementation
}
};
class NonterminalExpression : public AbstractExpression {
public:
NonterminalExpression(AbstractExpression* expression) : expression(expression) {}
void interpret(Context& context) override {
expression->interpret(context);
}
private:
AbstractExpression* expression;
};
16.迭代器模式(Iterator)
提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
class Iterator {
public:
virtual bool hasNext() = 0;
virtual int next() = 0;
};
class ConcreteIterator : public Iterator {
public:
ConcreteIterator(const std::vector<int>& items) : items(items), index(0) {}
bool hasNext() override {
return index < items.size();
}
int next() override {
return items[index++];
}
private:
std::vector<int> items;
size_t index;
};
class Aggregate {
public:
virtual Iterator* createIterator() = 0;
};
class ConcreteAggregate : public Aggregate {
public:
ConcreteAggregate() {
items = {1, 2, 3, 4, 5};
}
Iterator* createIterator() override {
return new ConcreteIterator(items);
}
private:
std::vector<int> items;
};
17.中介者模式(Mediator)
用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
class Mediator {
public:
virtual void notify(Component* sender, const std::string& event) = 0;
};
class ConcreteMediator : public Mediator {
public:
void setComponent1(Component* component) {
this->component1 = component;
}
void setComponent2(Component* component) {
this->component2 = component;
}
void notify(Component* sender, const std::string& event) override {
if (event == "A") {
component2->doB();
} else if (event == "B") {
component1->doA();
}
}
private:
Component* component1;
Component* component2;
};
class Component {
public:
Component(Mediator* mediator) : mediator(mediator) {}
void setMediator(Mediator* mediator) {
this->mediator = mediator;
}
protected:
Mediator* mediator;
};
class Component1 : public Component {
public:
using Component::Component;
void doA() {
mediator->notify(this, "A");
}
};
class Component2 : public Component {
public:
using Component::Component;
void doB() {
mediator->notify(this, "B");
}
};
18.备忘录模式(Memento)
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
class Memento {
public:
Memento(int state) : state(state) {}
int getState() {
return state;
}
private:
int state;
};
class Originator {
public:
void setState(int state) {
this->state = state;
}
int getState() {
return state;
}
Memento* saveStateToMemento() {
return new Memento(state);
}
void getStateFromMemento(Memento* memento) {
state = memento->getState();
}
private:
int state;
};
class Caretaker {
public:
void add(Memento* state) {
mementoList.push_back(state);
}
Memento* get(int index) {
return mementoList[index];
}
private:
std::vector<Memento*> mementoList;
};
19.观察者模式(Observer)
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
class Observer {
public:
virtual void update(int state) = 0;
};
class ConcreteObserver : public Observer {
public:
void update(int state) override {
// Implementation
}
};
class Subject {
public:
void attach(Observer* observer) {
observers.push_back(observer);
}
void detach(Observer* observer) {
observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
}
void notify() {
for (auto observer : observers) {
observer->update(state);
}
}
void setState(int state) {
this->state = state;
notify();
}
private:
std::vector<Observer*> observers;
int state;
};
20.状态模式(State)
允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
class State {
public:
virtual void handle() = 0;
};
class ConcreteStateA : public State {
public:
void handle() override {
// Implementation
}
};
class ConcreteStateB : public State {
public:
void handle() override {
// Implementation
}
};
class Context {
public:
void setState(State* state) {
this->state = state;
}
void request() {
state->handle();
}
private:
State* state;
};
21.策略模式(Strategy)
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。
class Strategy {
public:
virtual void execute() = 0;
};
class ConcreteStrategyA : public Strategy {
public:
void execute() override {
// Implementation
}
};
class ConcreteStrategyB : public Strategy {
public:
void execute() override {
// Implementation
}
};
class Context {
public:
void setStrategy(Strategy* strategy) {
this->strategy = strategy;
}
void executeStrategy() {
strategy->execute();
}
private:
Strategy* strategy;
};
22.模板方法模式(Template Method)
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
class AbstractClass {
public:
void templateMethod() {
primitiveOperation1();
primitiveOperation2();
}
virtual void primitiveOperation1() = 0;
virtual void primitiveOperation2() = 0;
};
class ConcreteClass : public AbstractClass {
public:
void primitiveOperation1() override {
// Implementation
}
void primitiveOperation2() override {
// Implementation
}
};
23.访问者模式(Visitor)
封装一些作用于某种数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。
class Element;
class Visitor {
public:
virtual void visit(Element* element) = 0;
};
class ConcreteVisitor : public Visitor {
public:
void visit(Element* element) override {
// Implementation
}
};
class Element {
public:
virtual void accept(Visitor* visitor) = 0;
};
class ConcreteElement : public Element {
public:
void accept(Visitor* visitor) override {
visitor->visit(this);
}
};
总结
设计模式是软件工程中的一种最佳实践,它们提供了在特定情境下解决常见设计问题的模板。设计模式分为三大类:创建型模式、结构型模式和行为型模式。
总的来说,设计模式提供了在软件开发中常见问题的解决方案,帮助开发者编写更灵活、可维护和可扩展的代码。通过理解和应用这些模式,开发者可以更有效地应对复杂的软件设计挑战。