设计模式(二十二)—— 享元模式

享元模式

定义

运用共享技术有效的支持大量细粒度对象的复用,通过共享已经存在的对象来减少需要创建的对象数量,避免大量相似类的创建开销,从而提高李彤资源利用率。

  • Flyweight:抽象享元角色,定义对象的外部状态和内部状态的接口或实现。
  • ConcreteFlyweight:具体享元角色,实现抽象角色定义的业务。该角色内部状态的处理应该与环境无关,不应该出现一个操作改变了内部状态,同时修改了外部状态。
  • unsharedConcreteFlyweight:不可共享的享元角色,不存在外部状态或者安全要求(如线程安全)不能使用共享技术的对象,该对象一般不会出现在享元工厂中。
  • FlyweightFactory:享元工厂,构造一个池容器,同时提供从池中获取对象的方法。

具体实现

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
public class UnsharedConcreteFlyweight {

private String info;

public UnsharedConcreteFlyweight(String info) {
this.info = info;
}

public String getInfo() {
return info;
}

public void setInfo(String info) {
this.info = info;
}
}

public interface Flyweight {
void operation(UnsharedConcreteFlyweight flyweight);
}

public class ConcreteFlyweight implements Flyweight {
private String key;

public ConcreteFlyweight(String key) {
this.key = key;
System.out.println("具体享元 "+key+"被创建");
}

@Override
public void operation(UnsharedConcreteFlyweight flyweight) {
System.out.print("具体享元"+key+"被调用,");
System.out.println("非享元信息是:"+flyweight.getInfo());
}
}

public class FlyweightFactory {

private HashMap<String, Flyweight> flyweights=new HashMap<String, Flyweight>();

public Flyweight getFlyweight(String key){
Flyweight flyweight=flyweights.get(key);
if(flyweight!=null) {
System.out.println("具体享元"+key+"已经存在,被成功获取!");
}else{
flyweight=new ConcreteFlyweight(key);
flyweights.put(key, flyweight);
}
return flyweight;
}
}

public static void main(String[] args) {
FlyweightFactory factory=new FlyweightFactory();
Flyweight f01=factory.getFlyweight("a");
Flyweight f02=factory.getFlyweight("a");
Flyweight f03=factory.getFlyweight("a");
Flyweight f11=factory.getFlyweight("b");
Flyweight f12=factory.getFlyweight("b");
f01.operation(new UnsharedConcreteFlyweight("第1次调用a。"));
f02.operation(new UnsharedConcreteFlyweight("第2次调用a。"));
f03.operation(new UnsharedConcreteFlyweight("第3次调用a。"));
f11.operation(new UnsharedConcreteFlyweight("第1次调用b。"));
f12.operation(new UnsharedConcreteFlyweight("第2次调用b。"));

}

// 输出
具体享元 a被创建
具体享元a已经存在,被成功获取!
具体享元a已经存在,被成功获取!
具体享元 b被创建
具体享元b已经存在,被成功获取!
具体享元a被调用,非享元信息是:第1次调用a。
具体享元a被调用,非享元信息是:第2次调用a。
具体享元a被调用,非享元信息是:第3次调用a。
具体享元b被调用,非享元信息是:第1次调用b。
具体享元b被调用,非享元信息是:第2次调用b。

优点

  • 减少程序创建对象数量,降低内存占用,增强系统性能。

缺点

  • 提高系统复杂性,需要将一些不能共享的状态外部化。

使用场景

  • 系统内存在大量相似对象
  • 细粒度的对象都具备较接近的外部状态,且内部状态与环境无关,也就是说对象没有特定身份。
  • 需要缓冲池的场景。

代码:GitHub


欢迎关注公众号:
公众号微信

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
显示 Gitment 评论