设计模式之装饰器模式
# 设计模式之装饰器模式
# 一、简介
将一个对象包装起来以增加新的行为和责任,同时又不改变其结构,这种模式称为装饰器模式
# 二、实现方式
抽象组件(Component)
需要装饰的接口/抽象类
被装饰者(ConcreteComponent)
实现了
Component
,需要装饰的具体对象抽象装饰者(Decorator)
实现了
Component
,并持有Component
对象的引用。具体装饰者(ConcreteDecorator)
负责给对象增加新的行为和责任
//Component定义了一个对象接口,通过装饰类可以给这些对象动态地添加职责
public abstract class Component {
public abstract void operation();
}
//ConcreteComponent是定义一个具体的对象,也可以给这个对象添加一些职责
public class ConcreteComponent extends Component {
@Override
public void operation() {
System.out.println("具体对象的操作");
}
}
/** Decorator,装饰抽象类,继承了Component
* 从外类来扩展Component类的功能,但对于Component来说,
* 是无需知道Decorator的存在的
*/
public abstract class Decorator extends Component {
protected Component component;
//获取被装饰的对象
public Component getComponent() {
return component;
}
//设置被装饰的对象
public void setComponent(Component component) {
this.component = component;
}
@Override
public void operation() {
if (component != null) {
component.operation();
}
}
}
//具体装饰类,可以为类加入新的行为
class ConcreteDecoratorA extends Decorator {
private String addedState;
@Override
public void operation() {
// 首先运行原Component的operation(),再执行本类的功能,如addedState,相当于对原Component进行了装饰
super.operation();
addedState = "A中的new state ";
System.out.println(addedState + "具体装饰对象A的操作");
}
}
class ConcreteDecoratorB extends Decorator {
@Override
public void operation() {
super.operation();
addedBehavior();
System.out.println("具体装饰对象B的操作");
}
public void addedBehavior() {
System.out.print("B中的新增行为 ");
}
}
class ConcreteDecoratorC extends Decorator {
@Override
public void operation() {
super.operation();
System.out.println("C没有特殊行为 " + "具体装饰对象C的操作");
}
}
//装饰模式客户端调用代码
public class DecoratorClient {
public static void main(String[] args) {
ConcreteComponent concreteComponent = new ConcreteComponent();
//声明装饰类A、B、C
ConcreteDecoratorA concreteDecoratorA = new ConcreteDecoratorA();
ConcreteDecoratorB concreteDecoratorB = new ConcreteDecoratorB();
ConcreteDecoratorC concreteDecoratorC = new ConcreteDecoratorC();
//装饰的过程就像是层层包装,不断地装饰类包装对象,达到添加功能的目的
concreteDecoratorA.setComponent(concreteComponent); //装饰类A包装对象
concreteDecoratorB.setComponent(concreteDecoratorA); //装饰类B包装装饰类A(对象已经被包装在装饰类A中)
concreteDecoratorC.setComponent(concreteDecoratorB); //装饰类C包装装饰类B
concreteDecoratorC.operation();
}
}
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
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
# 三、应用场景
# 1、MyBatis的二级缓存
Mybatis的二级缓存在结构设计上采用装饰器+责任链模式,Cache
由一层层装饰器包装起来,每一层都有各自的责任,例如:LruCache
缓存淘汰,SerializedCache
,序列化反序列化等
在上面的例子中:
Cache
相当于抽象组件。
PerpetualCache
它是一级缓存、二级缓存的最基本实现,只不过包装了一下HashMap,相当于具体被装饰者。
SerializedCache
、LruCache
等装饰类实现了Cache
接口,并持有Cache
对象的引用,相当是具体装饰者。
最后通过CacheBuilder
这个缓存构建类,来构建组合这些装饰器
public Cache build() {
//1. 设置默认的缓存类型(PerpetualCache)和缓存装饰器(LruCache)
setDefaultImplementations();
//通过反射创建缓存
Cache cache = newBaseCacheInstance(implementation, id);
//设额外属性,初始化Cache对象
setCacheProperties(cache);
// issue #352, do not apply decorators to custom caches
//2. 仅对内置缓存PerpetualCache应用装饰器
if (PerpetualCache.class.equals(cache.getClass())) {
for (Class<? extends Cache> decorator : decorators) {
//装饰者模式一个个包装cache
cache = newCacheDecoratorInstance(decorator, cache);
//又要来一遍设额外属性
setCacheProperties(cache);
}
//3. 应用标准的装饰者,比如LoggingCache,SynchronizedCache
cache = setStandardDecorators(cache);
} else if (!LoggingCache.class.isAssignableFrom(cache.getClass())) {
//4.如果是custom缓存,且不是日志,要加日志
cache = new LoggingCache(cache);
}
return cache;
}
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25