设计模式

设计模式概述

设计模式是解决软件设计中常见问题的可复用方案,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。设计模式的目的是:

  • 重用代码,提高开发效率
  • 使代码更容易理解和维护
  • 保证代码的可靠性和可扩展性
  • 促进团队成员之间的沟通

设计模式分为三大类:创建型模式、结构型模式和行为型模式。

创建型模式

创建型模式关注对象的创建过程,提供了创建对象的最佳方式,隐藏了创建逻辑,使代码更加灵活。

1. 工厂模式(Factory Pattern)

定义:定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。

UML 类图

  • Product:抽象产品
  • ConcreteProduct:具体产品
  • Factory:抽象工厂
  • ConcreteFactory:具体工厂

代码示例

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
#include <iostream>
#include <string>

// 抽象产品
class Shape {
public:
virtual void draw() = 0;
virtual ~Shape() {}
};

// 具体产品
class Circle : public Shape {
public:
void draw() override {
std::cout << "Drawing Circle" << std::endl;
}
};

class Rectangle : public Shape {
public:
void draw() override {
std::cout << "Drawing Rectangle" << std::endl;
}
};

// 抽象工厂
class ShapeFactory {
public:
virtual Shape* createShape() = 0;
virtual ~ShapeFactory() {}
};

// 具体工厂
class CircleFactory : public ShapeFactory {
public:
Shape* createShape() override {
return new Circle();
}
};

class RectangleFactory : public ShapeFactory {
public:
Shape* createShape() override {
return new Rectangle();
}
};

// 客户端
int main() {
ShapeFactory* circleFactory = new CircleFactory();
Shape* circle = circleFactory->createShape();
circle->draw();

ShapeFactory* rectangleFactory = new RectangleFactory();
Shape* rectangle = rectangleFactory->createShape();
rectangle->draw();

delete circle;
delete rectangle;
delete circleFactory;
delete rectangleFactory;

return 0;
}

适用场景

  • 当一个类不知道它所必须创建的对象的类时
  • 当一个类希望由它的子类来指定它所创建的对象时
  • 当类将创建对象的职责委托给多个帮助子类中的某一个,并且希望将哪一个帮助子类是代理者这一信息局部化时

2. 抽象工厂模式(Abstract Factory Pattern)

定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

UML 类图

  • AbstractFactory:抽象工厂
  • ConcreteFactory:具体工厂
  • AbstractProduct:抽象产品
  • ConcreteProduct:具体产品

代码示例

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
#include <iostream>
#include <string>

// 抽象产品A
class AbstractProductA {
public:
virtual ~AbstractProductA() {}
virtual std::string getName() = 0;
};

// 具体产品A1
class ProductA1 : public AbstractProductA {
public:
std::string getName() override {
return "Product A1";
}
};

// 具体产品A2
class ProductA2 : public AbstractProductA {
public:
std::string getName() override {
return "Product A2";
}
};

// 抽象产品B
class AbstractProductB {
public:
virtual ~AbstractProductB() {}
virtual std::string getName() = 0;
};

// 具体产品B1
class ProductB1 : public AbstractProductB {
public:
std::string getName() override {
return "Product B1";
}
};

// 具体产品B2
class ProductB2 : public AbstractProductB {
public:
std::string getName() override {
return "Product B2";
}
};

// 抽象工厂
class AbstractFactory {
public:
virtual ~AbstractFactory() {}
virtual AbstractProductA* createProductA() = 0;
virtual AbstractProductB* createProductB() = 0;
};

// 具体工厂1
class ConcreteFactory1 : public AbstractFactory {
public:
AbstractProductA* createProductA() override {
return new ProductA1();
}

AbstractProductB* createProductB() override {
return new ProductB1();
}
};

// 具体工厂2
class ConcreteFactory2 : public AbstractFactory {
public:
AbstractProductA* createProductA() override {
return new ProductA2();
}

AbstractProductB* createProductB() override {
return new ProductB2();
}
};

// 客户端
int main() {
// 使用工厂1创建产品族1
AbstractFactory* factory1 = new ConcreteFactory1();
AbstractProductA* productA1 = factory1->createProductA();
AbstractProductB* productB1 = factory1->createProductB();

std::cout << productA1->getName() << std::endl;
std::cout << productB1->getName() << std::endl;

// 使用工厂2创建产品族2
AbstractFactory* factory2 = new ConcreteFactory2();
AbstractProductA* productA2 = factory2->createProductA();
AbstractProductB* productB2 = factory2->createProductB();

std::cout << productA2->getName() << std::endl;
std::cout << productB2->getName() << std::endl;

// 清理资源
delete productA1;
delete productB1;
delete factory1;
delete productA2;
delete productB2;
delete factory2;

return 0;
}

适用场景

  • 当一个系统要独立于它的产品的创建、组合和表示时
  • 当一个系统要由多个产品系列中的一个来配置时
  • 当你要强调一系列相关的产品对象的设计以便进行联合使用时

3. 单例模式(Singleton Pattern)

定义:确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例。

UML 类图

  • Singleton:单例类

代码示例(线程安全的懒汉式):

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
#include <iostream>
#include <mutex>

class Singleton {
private:
// 私有构造函数
Singleton() {
std::cout << "Singleton 构造函数调用" << std::endl;
}

// 私有析构函数
~Singleton() {
std::cout << "Singleton 析构函数调用" << std::endl;
}

// 私有拷贝构造函数
Singleton(const Singleton&) = delete;

// 私有赋值操作符
Singleton& operator=(const Singleton&) = delete;

// 静态成员变量
static Singleton* instance;
static std::mutex mutex;

public:
// 静态获取实例方法
static Singleton* getInstance() {
// 双重检查锁定
if (instance == nullptr) {
std::lock_guard<std::mutex> lock(mutex);
if (instance == nullptr) {
instance = new Singleton();
}
}
return instance;
}

// 静态销毁实例方法
static void destroyInstance() {
std::lock_guard<std::mutex> lock(mutex);
if (instance != nullptr) {
delete instance;
instance = nullptr;
}
}

// 业务方法
void showMessage() {
std::cout << "Hello Singleton!" << std::endl;
}
};

// 静态成员变量初始化
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mutex;

// 客户端
int main() {
// 获取单例实例
Singleton* singleton1 = Singleton::getInstance();
Singleton* singleton2 = Singleton::getInstance();

// 验证是否是同一个实例
std::cout << "singleton1 地址: " << singleton1 << std::endl;
std::cout << "singleton2 地址: " << singleton2 << std::endl;

// 调用业务方法
singleton1->showMessage();

// 销毁实例
Singleton::destroyInstance();

return 0;
}

适用场景

  • 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时
  • 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时

4. 建造者模式(Builder Pattern)

定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

UML 类图

  • Product:产品类
  • Builder:抽象建造者
  • ConcreteBuilder:具体建造者
  • Director:指挥者

代码示例

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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <iostream>
#include <string>
#include <vector>

// 产品类
class Computer {
private:
std::vector<std::string> parts;

public:
void addPart(const std::string& part) {
parts.push_back(part);
}

void show() {
std::cout << "Computer Parts:" << std::endl;
for (const auto& part : parts) {
std::cout << "- " << part << std::endl;
}
}
};

// 抽象建造者
class ComputerBuilder {
protected:
Computer* computer;

public:
ComputerBuilder() {
computer = new Computer();
}

virtual ~ComputerBuilder() {
delete computer;
}

Computer* getComputer() {
return computer;
}

virtual void buildCPU() = 0;
virtual void buildMemory() = 0;
virtual void buildHardDrive() = 0;
virtual void buildDisplay() = 0;
};

// 具体建造者:游戏电脑
class GamingComputerBuilder : public ComputerBuilder {
public:
void buildCPU() override {
computer->addPart("Intel Core i9 CPU");
}

void buildMemory() override {
computer->addPart("32GB DDR4 RAM");
}

void buildHardDrive() override {
computer->addPart("2TB SSD");
}

void buildDisplay() override {
computer->addPart("4K Gaming Monitor");
}
};

// 具体建造者:办公电脑
class OfficeComputerBuilder : public ComputerBuilder {
public:
void buildCPU() override {
computer->addPart("Intel Core i5 CPU");
}

void buildMemory() override {
computer->addPart("16GB DDR4 RAM");
}

void buildHardDrive() override {
computer->addPart("512GB SSD");
}

void buildDisplay() override {
computer->addPart("24-inch Monitor");
}
};

// 指挥者
class Director {
private:
ComputerBuilder* builder;

public:
Director(ComputerBuilder* builder) : builder(builder) {}

void setBuilder(ComputerBuilder* builder) {
this->builder = builder;
}

Computer* construct() {
builder->buildCPU();
builder->buildMemory();
builder->buildHardDrive();
builder->buildDisplay();
return builder->getComputer();
}
};

// 客户端
int main() {
// 创建游戏电脑
GamingComputerBuilder gamingBuilder;
Director director(&gamingBuilder);
Computer* gamingComputer = director.construct();
std::cout << "游戏电脑配置:" << std::endl;
gamingComputer->show();

// 创建办公电脑
OfficeComputerBuilder officeBuilder;
director.setBuilder(&officeBuilder);
Computer* officeComputer = director.construct();
std::cout << "\n办公电脑配置:" << std::endl;
officeComputer->show();

// 清理资源
delete gamingComputer;
delete officeComputer;

return 0;
}

适用场景

  • 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时
  • 当构造过程必须允许被构造的对象有不同的表示时

5. 原型模式(Prototype Pattern)

定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

UML 类图

  • Prototype:抽象原型类
  • ConcretePrototype:具体原型类

代码示例

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
#include <iostream>
#include <string>
#include <memory>

// 抽象原型类
class Prototype {
public:
virtual ~Prototype() {}
virtual std::unique_ptr<Prototype> clone() const = 0;
virtual void show() const = 0;
};

// 具体原型类
class ConcretePrototype : public Prototype {
private:
std::string name;
int age;

public:
ConcretePrototype(const std::string& name, int age)
: name(name), age(age) {}

// 拷贝构造函数
ConcretePrototype(const ConcretePrototype& other)
: name(other.name), age(other.age) {
std::cout << "ConcretePrototype 拷贝构造函数调用" << std::endl;
}

// 克隆方法
std::unique_ptr<Prototype> clone() const override {
return std::make_unique<ConcretePrototype>(*this);
}

void show() const override {
std::cout << "Name: " << name << ", Age: " << age << std::endl;
}

// 设置属性
void setName(const std::string& newName) {
name = newName;
}

void setAge(int newAge) {
age = newAge;
}
};

// 客户端
int main() {
// 创建原型对象
std::unique_ptr<Prototype> prototype = std::make_unique<ConcretePrototype>("张三", 25);

// 克隆原型对象
std::unique_ptr<Prototype> clone1 = prototype->clone();

// 修改克隆对象的属性
ConcretePrototype* concreteClone = dynamic_cast<ConcretePrototype*>(clone1.get());
if (concreteClone) {
concreteClone->setName("李四");
concreteClone->setAge(30);
}

// 创建另一个克隆对象
std::unique_ptr<Prototype> clone2 = prototype->clone();

// 显示所有对象
std::cout << "原型对象:" << std::endl;
prototype->show();

std::cout << "\n克隆对象1:" << std::endl;
clone1->show();

std::cout << "\n克隆对象2:" << std::endl;
clone2->show();

return 0;
}

适用场景

  • 当要实例化的类是在运行时指定时
  • 当一个类的实例只能有几个不同状态组合中的一种时
  • 当对象创建过程比较复杂,而复制一个已有对象比创建一个新对象更高效时

结构型模式

结构型模式关注类和对象的组合,通过继承或组合来组合类或对象,从而形成更大的结构。

1. 适配器模式(Adapter Pattern)

定义:将一个类的接口转换成客户端所期望的另一种接口,从而使原本接口不匹配而无法一起工作的两个类能够一起工作。

UML 类图

  • Target:目标接口
  • Adaptee:适配者类
  • Adapter:适配器类

代码示例(类适配器):

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
#include <iostream>
#include <string>

// 目标接口
class Target {
public:
virtual ~Target() {}
virtual void request() const {
std::cout << "Target: Default request." << std::endl;
}
};

// 适配者类
class Adaptee {
public:
void specificRequest() const {
std::cout << "Adaptee: Specific request." << std::endl;
}
};

// 适配器类(类适配器,使用多重继承)
class Adapter : public Target, private Adaptee {
public:
void request() const override {
std::cout << "Adapter: Translating request to Adaptee's interface." << std::endl;
specificRequest();
}
};

// 客户端
void clientCode(const Target* target) {
target->request();
}

int main() {
std::cout << "Client: Using Target directly." << std::endl;
Target* target = new Target();
clientCode(target);

std::cout << "\nClient: Using Adaptee with Adapter." << std::endl;
Adapter* adapter = new Adapter();
clientCode(adapter);

delete target;
delete adapter;

return 0;
}

适用场景

  • 当你想使用一个已经存在的类,但它的接口不符合你的需求时
  • 当你想创建一个可复用的类,该类可以与其他不相关的类或不可预见的类(即接口可能不一定兼容的类)协同工作时

2. 桥接模式(Bridge Pattern)

定义:将抽象部分与它的实现部分分离,使它们都可以独立地变化。

UML 类图

  • Abstraction:抽象类
  • RefinedAbstraction:扩充抽象类
  • Implementor:实现接口
  • ConcreteImplementor:具体实现类

代码示例

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 <iostream>
#include <string>

// 实现接口
class Implementor {
public:
virtual ~Implementor() {}
virtual void operationImpl() const = 0;
};

// 具体实现类A
class ConcreteImplementorA : public Implementor {
public:
void operationImpl() const override {
std::cout << "ConcreteImplementorA operation" << std::endl;
}
};

// 具体实现类B
class ConcreteImplementorB : public Implementor {
public:
void operationImpl() const override {
std::cout << "ConcreteImplementorB operation" << std::endl;
}
};

// 抽象类
class Abstraction {
protected:
Implementor* implementor;

public:
Abstraction(Implementor* impl) : implementor(impl) {}

virtual ~Abstraction() {}

virtual void operation() const {
implementor->operationImpl();
}
};

// 扩充抽象类
class RefinedAbstraction : public Abstraction {
public:
RefinedAbstraction(Implementor* impl) : Abstraction(impl) {}

void operation() const override {
std::cout << "RefinedAbstraction: " << std::endl;
Abstraction::operation();
}
};

// 客户端
int main() {
Implementor* implA = new ConcreteImplementorA();
Abstraction* abstractionA = new RefinedAbstraction(implA);
abstractionA->operation();

std::cout << "\n";

Implementor* implB = new ConcreteImplementorB();
Abstraction* abstractionB = new RefinedAbstraction(implB);
abstractionB->operation();

delete implA;
delete abstractionA;
delete implB;
delete abstractionB;

return 0;
}

适用场景

  • 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时
  • 当你想避免在抽象和它的实现之间建立固定的绑定关系时

3. 装饰模式(Decorator Pattern)

定义:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式比生成子类更为灵活。

UML 类图

  • Component:抽象组件
  • ConcreteComponent:具体组件
  • Decorator:抽象装饰器
  • ConcreteDecorator:具体装饰器

代码示例

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
#include <iostream>
#include <string>

// 抽象组件
class Component {
public:
virtual ~Component() {}
virtual std::string operation() const = 0;
};

// 具体组件
class ConcreteComponent : public Component {
public:
std::string operation() const override {
return "ConcreteComponent";
}
};

// 抽象装饰器
class Decorator : public Component {
protected:
Component* component;

public:
Decorator(Component* comp) : component(comp) {}

~Decorator() {
delete component;
}

std::string operation() const override {
return component->operation();
}
};

// 具体装饰器A
class ConcreteDecoratorA : public Decorator {
public:
ConcreteDecoratorA(Component* comp) : Decorator(comp) {}

std::string operation() const override {
return "ConcreteDecoratorA(" + Decorator::operation() + ")";
}
};

// 具体装饰器B
class ConcreteDecoratorB : public Decorator {
public:
ConcreteDecoratorB(Component* comp) : Decorator(comp) {}

std::string operation() const override {
return "ConcreteDecoratorB(" + Decorator::operation() + ")";
}
};

// 客户端
void clientCode(Component* component) {
std::cout << "Result: " << component->operation() << std::endl;
}

int main() {
// 使用具体组件
Component* simple = new ConcreteComponent();
std::cout << "Client: I've got a simple component." << std::endl;
clientCode(simple);

// 使用装饰器A装饰组件
Component* decorator1 = new ConcreteDecoratorA(simple);
std::cout << "\nClient: Now I've got a decorated component." << std::endl;
clientCode(decorator1);

// 使用装饰器B装饰已经装饰过的组件
Component* decorator2 = new ConcreteDecoratorB(decorator1);
std::cout << "\nClient: Now I've got a double decorated component." << std::endl;
clientCode(decorator2);

delete decorator2; // 会自动删除所有嵌套的组件和装饰器

return 0;
}

适用场景

  • 当你需要给一个现有的类添加新的功能,但又不希望通过继承来实现时
  • 当你需要动态地给一个对象添加功能,这些功能也可以动态地被撤销时

行为型模式

行为型模式关注对象之间的通信和职责分配,描述了对象之间如何协作以及如何分配职责。

1. 策略模式(Strategy Pattern)

定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。策略模式让算法独立于使用它的客户而变化。

UML 类图

  • Context:上下文类
  • Strategy:策略接口
  • ConcreteStrategy:具体策略类

代码示例

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 <iostream>
#include <string>
#include <memory>

// 策略接口
class Strategy {
public:
virtual ~Strategy() {}
virtual std::string doOperation(const std::string& data) const = 0;
};

// 具体策略类A
class ConcreteStrategyA : public Strategy {
public:
std::string doOperation(const std::string& data) const override {
std::string result = data;
// 执行策略A的操作,例如排序
std::sort(result.begin(), result.end());
return result;
}
};

// 具体策略类B
class ConcreteStrategyB : public Strategy {
public:
std::string doOperation(const std::string& data) const override {
std::string result = data;
// 执行策略B的操作,例如反转
std::reverse(result.begin(), result.end());
return result;
}
};

// 上下文类
class Context {
private:
std::unique_ptr<Strategy> strategy;

public:
Context(std::unique_ptr<Strategy> strat) : strategy(std::move(strat)) {}

void setStrategy(std::unique_ptr<Strategy> strat) {
strategy = std::move(strat);
}

std::string executeStrategy(const std::string& data) const {
return strategy->doOperation(data);
}
};

// 客户端
int main() {
std::string data = "abcdefg";

// 使用策略A
Context context(std::make_unique<ConcreteStrategyA>());
std::cout << "原始数据: " << data << std::endl;
std::cout << "策略A结果: " << context.executeStrategy(data) << std::endl;

// 切换到策略B
context.setStrategy(std::make_unique<ConcreteStrategyB>());
std::cout << "策略B结果: " << context.executeStrategy(data) << std::endl;

return 0;
}

适用场景

  • 当你有许多相关的类,它们仅在行为上有所不同时
  • 当你需要一个算法的不同变体时
  • 当一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现时

2. 观察者模式(Observer Pattern)

定义:定义对象间的一种一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

UML 类图

  • Subject:主题类
  • Observer:观察者接口
  • ConcreteObserver:具体观察者类

代码示例

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
#include <iostream>
#include <string>
#include <vector>
#include <memory>

// 前向声明
class Subject;

// 观察者接口
class Observer {
public:
virtual ~Observer() {}
virtual void update(const Subject& subject) = 0;
};

// 主题类
class Subject {
private:
std::vector<Observer*> observers;
int state;

public:
Subject() : state(0) {}

// 注册观察者
void attach(Observer* observer) {
observers.push_back(observer);
}

// 移除观察者
void detach(Observer* observer) {
auto it = std::find(observers.begin(), observers.end(), observer);
if (it != observers.end()) {
observers.erase(it);
}
}

// 通知所有观察者
void notify() {
for (Observer* observer : observers) {
observer->update(*this);
}
}

// 设置状态
void setState(int newState) {
if (state != newState) {
state = newState;
notify();
}
}

// 获取状态
int getState() const {
return state;
}
};

// 具体观察者类
class ConcreteObserver : public Observer {
private:
std::string name;
int observerState;

public:
ConcreteObserver(const std::string& name) : name(name), observerState(0) {}

void update(const Subject& subject) override {
observerState = subject.getState();
std::cout << "观察者 " << name << " 状态更新为: " << observerState << std::endl;
}
};

// 客户端
int main() {
// 创建主题
Subject subject;

// 创建观察者
ConcreteObserver observer1("观察者1");
ConcreteObserver observer2("观察者2");
ConcreteObserver observer3("观察者3");

// 注册观察者
subject.attach(&observer1);
subject.attach(&observer2);
subject.attach(&observer3);

// 改变主题状态
std::cout << "改变主题状态为 10" << std::endl;
subject.setState(10);

// 移除一个观察者
std::cout << "\n移除观察者2" << std::endl;
subject.detach(&observer2);

// 再次改变主题状态
std::cout << "\n改变主题状态为 20" << std::endl;
subject.setState(20);

return 0;
}

适用场景

  • 当一个对象的改变需要同时改变其他对象时
  • 当一个对象必须通知其他对象,而又不希望这些对象与它紧密耦合时

总结

设计模式是软件工程中的重要概念,掌握设计模式可以帮助开发者编写更加灵活、可维护和可扩展的代码。本文介绍了几种常用的设计模式,包括:

  1. 创建型模式:工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式
  2. 结构型模式:适配器模式、桥接模式、装饰模式
  3. 行为型模式:策略模式、观察者模式

每种设计模式都有其特定的适用场景和优缺点,开发者应根据实际需求选择合适的设计模式。在实际开发中,往往需要结合多种设计模式来解决复杂的问题。