CS-Notes/notes/设计模式 - 装饰.md
2020-11-17 00:32:18 +08:00

108 lines
3.2 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 装饰Decorator
### Intent
为对象动态添加功能
### Class Diagram
装饰者Decorator和具体组件ConcreteComponent都继承自组件Component具体组件的方法实现不需要依赖于其它对象而装饰者组合了一个组件这样它可以装饰其它装饰者或者具体组件所谓装饰就是把这个装饰者套在被装饰者之上从而动态扩展被装饰者的功能装饰者的方法有一部分是自己的这属于它的功能然后调用被装饰者的方法实现从而也保留了被装饰者的功能可以看到具体组件应当是装饰层次的最低层因为只有具体组件的方法实现不需要依赖于其它对象
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/6b833bc2-517a-4270-8a5e-0a5f6df8cd96.png"/> </div><br>
### Implementation
设计不同种类的饮料饮料可以添加配料比如可以添加牛奶并且支持动态添加新配料每增加一种配料该饮料的价格就会增加要求计算一种饮料的价格
下图表示在 DarkRoast 饮料上新增新添加 Mocha 配料之后又添加了 Whip 配料DarkRoast Mocha 包裹Mocha 又被 Whip 包裹它们都继承自相同父类都有 cost() 方法外层类的 cost() 方法调用了内层类的 cost() 方法
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/c9cfd600-bc91-4f3a-9f99-b42f88a5bb24.jpg" width="600"/> </div><br>
```java
public interface Beverage {
double cost();
}
```
```java
public class DarkRoast implements Beverage {
@Override
public double cost() {
return 1;
}
}
```
```java
public class HouseBlend implements Beverage {
@Override
public double cost() {
return 1;
}
}
```
```java
public abstract class CondimentDecorator implements Beverage {
protected Beverage beverage;
}
```
```java
public class Milk extends CondimentDecorator {
public Milk(Beverage beverage) {
this.beverage = beverage;
}
@Override
public double cost() {
return 1 + beverage.cost();
}
}
```
```java
public class Mocha extends CondimentDecorator {
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
@Override
public double cost() {
return 1 + beverage.cost();
}
}
```
```java
public class Client {
public static void main(String[] args) {
Beverage beverage = new HouseBlend();
beverage = new Mocha(beverage);
beverage = new Milk(beverage);
System.out.println(beverage.cost());
}
}
```
```html
3.0
```
### 设计原则
类应该对扩展开放对修改关闭也就是添加新功能时不需要修改代码饮料可以动态添加新的配料而不需要去修改饮料的代码
不可能把所有的类设计成都满足这一原则应当把该原则应用于最有可能发生改变的地方
### JDK
- java.io.BufferedInputStream(InputStream)
- java.io.DataInputStream(InputStream)
- java.io.BufferedOutputStream(OutputStream)
- java.util.zip.ZipOutputStream(OutputStream)
- java.util.Collections#checked[List|Map|Set|SortedSet|SortedMap]()