Skip to content

Commit 3a58847

Browse files
committed
添加 装饰模式 README
1 parent d07f750 commit 3a58847

File tree

3 files changed

+154
-0
lines changed

3 files changed

+154
-0
lines changed

decorator/README.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# 装饰模式 ( Decorator )
2+
3+
## 用途
4+
用于动态地给一个对象添加一些额外的职责。 就增加功能来说, Decorator模式相比生成子类更为灵活。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
5+
6+
纯粹的装饰模式很难找到,大多数的装饰模式的实现都是“半透明”的,而不是完全透明的。换言之,允许装饰模式改变接口,增加新的方法。半透明的装饰模式是介于装饰模式和适配器模式之间的。适配器模式的用意是改变所考虑的类的接口,也可以通过改写一个或几个方法,或增加新的方法来增强或改变所考虑的类的功能。 大多数的装饰模式实际上是半透明的装饰模式,这样的装饰模式也称做半装饰、半适配器模式。
7+
8+
## 适用场景
9+
10+
以下情况使用Decorator模式
11+
* 在不影响其他对象的情况下, 以动态、 透明的方式给单个对象添加职责。
12+
* 处理那些可以撤消的职责。
13+
* 当不能采用生成子类的方法进行扩充时。 一种情况是, 可能有大量独立的扩展, 为支持每一种组合将产生大量的子类, 使得子类数目呈爆炸性增长。 另一种情况可能是因为类定义被隐藏, 或类定义不能用于生成子类。
14+
15+
## 模式要点
16+
17+
![](uml/Decorator.png)
18+
19+
### 组成部分
20+
* Component:定义一个对象接口, 可以给这些对象动态地添加职责。
21+
* ConcreteComponent:定义一个对象, 可以给这个对象添加一些职责。
22+
* Decorator:持有一个指向 Component 对象的引用,并定义一个与 Component 接口一致的接口。
23+
* ConcreteDecorator:一向组件添加职责。
24+
25+
### 协作原理
26+
* Decorator 将请求转发给它的 Component 对象, 并有可能在转发请求前后执行一些附加的动作。
27+
28+
## 实例分析
29+
![](uml/Decorator_impl.png)
30+
铁匠和木匠同时制作一把铁锤,第一种方案是木匠制作锤把,铁匠制作锤头;第二中方案是铁匠先制作锤把再制作锤头(假定这里的木匠只会制作锤把)。制作过程分为三部分:1.对材料进行初步的检查,2.进行制造并把部件安装起来以供后面的操作,3.完成之后再次进行检查,确保没有质量问题。
31+
32+
首先定义“操作”接口,包括前后两次检查以及安装的操作。
33+
34+
```
35+
/**
36+
* 流水线上操作行为的接口
37+
*/
38+
public interface Operation {
39+
40+
void checkBefore();
41+
42+
void join();
43+
44+
void chekcAfter();
45+
}
46+
```
47+
现在只由木匠制作锤把,定义一个木匠的操作类 CarpenterOperation
48+
```
49+
/**
50+
* 木匠的工作
51+
*/
52+
public class CarpenterOperation implements Operation {
53+
54+
private static final Logger LOGGER = LoggerFactory.getLogger(CarpenterOperation.class);
55+
56+
@Override
57+
public void checkBefore() {
58+
LOGGER.info("检查木材");
59+
}
60+
61+
@Override
62+
public void join() {
63+
LOGGER.info("打造锤把");
64+
}
65+
66+
@Override
67+
public void chekcAfter() {
68+
LOGGER.info("检查成品锤把");
69+
}
70+
}
71+
```
72+
由于某些原因,铁匠决定自己制作锤把,现在铁匠身兼双职,将木匠的工作也承担了。定义一个铁匠操作类 HammerSmith
73+
```
74+
/**
75+
* 铁匠
76+
*/
77+
public class HammerSmithOperation implements Operation {
78+
79+
private static final Logger LOGGER = LoggerFactory.getLogger(HammerSmithOperation.class);
80+
private Operation previousOperation;
81+
82+
public HammerSmithOperation(Operation previousOperation) {
83+
this.previousOperation = previousOperation;
84+
}
85+
86+
@Override
87+
public void checkBefore() {
88+
previousOperation.checkBefore();
89+
LOGGER.info("检查铁材");
90+
}
91+
92+
@Override
93+
public void join() {
94+
previousOperation.join();
95+
LOGGER.info("打造锤头");
96+
}
97+
98+
@Override
99+
public void chekcAfter() {
100+
previousOperation.chekcAfter();
101+
LOGGER.info("检查成品锤头");
102+
}
103+
}
104+
```
105+
106+
同样实现了“操作”的接口,铁匠的每个操作都包含了木匠相应的操作,相当于对木匠的操作增加了一层包裹和扩展。这种包装就是 Decorator 模式中的装饰。
107+
108+
现在分别让木匠和铁匠进行一系列操作
109+
```
110+
/**
111+
* Decorator
112+
*/
113+
public class Application {
114+
115+
private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);
116+
117+
public static void main(String[] args) {
118+
LOGGER.info("仅由木匠制作锤把");
119+
Operation carpenter = new CarpenterOperation();
120+
carpenter.checkBefore();
121+
carpenter.join();
122+
carpenter.chekcAfter();
123+
124+
LOGGER.info("由铁匠完成锤把以及锤头的制作");
125+
Operation hammerSmith = new HammerSmithOperation(carpenter);
126+
hammerSmith.checkBefore();
127+
hammerSmith.join();
128+
hammerSmith.chekcAfter();
129+
}
130+
}
131+
```
132+
输出如下内容
133+
```
134+
仅由木匠制作锤把
135+
检查木材
136+
打造锤把
137+
检查成品锤把
138+
139+
由铁匠完成锤把以及锤头的制作
140+
检查木材
141+
检查铁材
142+
打造锤把
143+
打造锤头
144+
检查成品锤把
145+
检查成品锤头
146+
```
147+
148+
## 效果
149+
### 优点
150+
1. 装饰模式和静态继承的机制的作用都是对现有的类增加新的功能,但装饰模式有着比静态继承更灵活的组合方式。装饰模式可以在运行的时候决定需要增加还是去除一种“装饰”以及什么“装饰”。静态继承则没有这样的灵活性,它对类功能的扩展是在运行之前就确定了的。
151+
2. 得益于装饰模式在组合上的灵活性和便利性,我们可以将各种装饰类进行组合,从而较为简单的创造各种不同的行为集合,实现多种多样的功能。
152+
### 缺点
153+
1. 装饰者的对象和它装饰的对象本质上是完全不同的,装饰模式会生成许多的对象,导致区分各种对象变得困难
154+
2. 由于使用相同的标识,对于程序的理解和拍错过程的难度也会随之增加

decorator/uml/Decorator.png

18.1 KB
Loading

decorator/uml/Decorator_impl.png

19 KB
Loading

0 commit comments

Comments
 (0)