人的知识就好比一个圆圈,圆圈里面是已知的,圆圈外面是未知的。你知道得越多,圆圈也就越大,你不知道的也就越多。

0%

设计模式--享元模式

定义

享元模式让某个类的一个实例能用来提供许多“虚拟实例”。

角色

  • 抽象享元类(Flyweight):通常是一个接口或抽象类,向外界提供享元对象的内部数据或外部数据。
  • 具体享元类(Concrete Flyweight):具体实现内部数据共享的类。
  • 享元工厂类(Flyweight Factory):用于创建和管理享元对象的工厂类。

类图

Flyweight UML

实现

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
/**
* 抽象享元类
*/
public interface Flyweight {

/**
* 操作
* 外部状态在使用时由外部设置,不保存在享元对象中,即使是同一个对象,在每一次调用时也可以传入不同的外部状态
*
* @param extrinsicState 外部状态
*/
void operation(String extrinsicState);

/**
* 内部状态
*
* @return 内部状态
*/
String getIntrinsicState();
}

/**
* 具体享元类
*/
public class ConcreteFlyweight implements Flyweight {
/**
* 内部状态
*/
private String intrinsicState;

public ConcreteFlyweight(String intrinsicState) {
this.intrinsicState = intrinsicState;
}

@Override
public void operation(String extrinsicState) {
System.out.println(String.format("内部状态:%s;外部状态:%s", intrinsicState, extrinsicState));
}

@Override
public String getIntrinsicState() {
return intrinsicState;
}
}

/**
* 享元工厂类
*/
public class FlyweightFactory {
public static final Map<String, Flyweight> FLYWEIGHT_MAP = new HashMap<>();

public static Flyweight getFlyweight(String intrinsicState) {
// 如果在享元池中存在对象,则直接获取
if (FLYWEIGHT_MAP.containsKey(intrinsicState)) {
return FLYWEIGHT_MAP.get(intrinsicState);
}
// 否则,新建对象,并放入到享元池
else {
ConcreteFlyweight flyweight = new ConcreteFlyweight(intrinsicState);
FLYWEIGHT_MAP.put(intrinsicState, flyweight);
return flyweight;
}
}
}

优缺点

优点

  • 大大减少对象的创建,降低系统的内存,使效率提高

缺点

  • 提高了系统的复杂度,需要分理出外部状态和内部状态,而且外部状态具有固化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱

适用场景

  • 系统有大量相似对象
  • 需要缓冲池的场景

模式应用

  • 连接池
  • 线程池
  • 字符串常量池
小礼物走一走,来 Github 关注我