享元模式(Flyweight Pattern)
# 享元模式(Flyweight Pattern)
# 概念
享元模式是一种结构设计模式,旨在通过共享对象来最小化内存使用和提高性能。它将对象分为可共享的内部状态和不可共享的外部状态。内部状态存储在享元对象内部,并可以在多个上下文中共享,而外部状态是根据上下文变化而变化的。
# 思想
享元模式的核心思想是通过共享对象来减少内存占用。它将相似的对象划分为内部状态和外部状态,其中内部状态可以共享,而外部状态可以在运行时传递。
# 角色
- Flyweight(享元):定义享元对象的接口,包含需要外部状态操作的方法。
- ConcreteFlyweight(具体享元):实现享元接口,存储并处理内部状态。
- UnsharedConcreteFlyweight(非共享具体享元):不可共享的具体享元,包含不能在共享池中共享的额外状态信息。
- FlyweightFactory(享元工厂):负责创建和管理享元对象,维护一个享元池用于存储和复用已创建的享元对象。
- Client(客户端):使用享元对象的客户端,通过享元工厂获取享元对象并操作外部状态。
# 优点
- 减少内存占用:通过共享内部状态,可以减少系统中对象的数量,节省内存空间。
- 提高性能:由于减少了对象数量,可以减少对象的创建和销毁次数,从而提高系统性能。
- 简化外部状态:外部状态由客户端传入,享元对象只需关注内部状态,简化了对象的复杂性。
# 缺点
- 对象共享可能导致线程安全问题:如果多个线程同时访问共享对象并修改其外部状态,需要确保线程安全性。
- 需要区分内部状态和外部状态:设计中需要明确划分内部状态和外部状态,增加了系统的复杂性。
# 类图
@startuml
class Client {
- state: string
+ setState(state: string)
+ operation(): void
}
interface Flyweight {
+ operation(state: string): void
}
class ConcreteFlyweight implements Flyweight {
- intrinsicState: string
+ operation(state: string): void
}
class UnsharedConcreteFlyweight implements Flyweight {
- allState: string
+ operation(state: string): void
}
class FlyweightFactory {
- flyweights: Flyweight[]
+ getFlyweight(key: string): Flyweight
}
Client --> Flyweight
Flyweight <|.. ConcreteFlyweight
Flyweight <|.. UnsharedConcreteFlyweight
FlyweightFactory --> Flyweight
@enduml
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
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
# 示例代码
下面是一个简单的示例代码,使用C++实现享元模式:
#include <iostream>
#include <unordered_map>
class Flyweight {
public:
virtual void operation(const std::string& state) = 0;
};
class ConcreteFlyweight : public Flyweight {
private:
std::string intrinsicState;
public:
ConcreteFlyweight(const std::string& intrinsicState) : intrinsicState(intrinsicState) {}
void operation(const std::string& state) override {
std::cout << "Intrinsic State: " << intrinsicState << ", Extrinsic State: " << state << std::endl;
}
};
class FlyweightFactory {
private:
std::unordered_map<std::string, Flyweight*> flyweights;
public:
Flyweight* getFlyweight(const std::string& key) {
if (flyweights.find(key) == flyweights.end()) {
flyweights[key] = new ConcreteFlyweight(key);
}
return flyweights[key];
}
};
int main() {
FlyweightFactory factory;
Flyweight* flyweight1 = factory.getFlyweight("SharedState");
flyweight1->operation("ExternalState1");
Flyweight* flyweight2 = factory.getFlyweight("SharedState");
flyweight2->operation("ExternalState2");
Flyweight* flyweight3 = factory.getFlyweight("UnsharedState");
flyweight3->operation("ExternalState3");
return 0;
}
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
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
# 代码运行结果
Intrinsic State: SharedState, Extrinsic State: ExternalState1
Intrinsic State: SharedState, Extrinsic State: ExternalState2
Intrinsic State: UnsharedState, Extrinsic State: ExternalState3
1
2
3
2
3
示例代码中,我们定义了一个Flyweight
接口,ConcreteFlyweight
和UnsharedConcreteFlyweight
类分别实现了该接口。FlyweightFactory
类负责创建和管理享元对象,并使用哈希表(unordered_map)来存储已创建的享元对象。
在main
函数中,我们通过FlyweightFactory
获取享元对象,并调用其operation
方法,传入外部状态。可以看到,对于相同的内部状态("SharedState"),返回的享元对象是同一个,而对于不可共享的额外状态("UnsharedState"),返回的是不同的对象。
代码运行结果显示了每个享元对象的内部状态和传入的外部状态。
编辑 (opens new window)
上次更新: 2023/06/09, 13:17:31
- 01
- Linux系统移植(五)--- 制作、烧录镜像并启动Linux02-05
- 03
- Linux系统移植(三)--- Linux kernel移植02-05