装饰器模式
概述
装饰器模式主要是在不更改原有类的情况下为其增加功能. 也就是用其他类(装饰器)包含原有类的方式.
实现
比如我们有一个咖啡接口, 和一个已经实现的咖啡实体类. 我们后续想往咖啡中自由添加调料, 而不改变 SimpleCoffee 的实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
interface Coffee {
/** 获取价格 */
double getCost();
/** 获取配料 */
String getIngredients();
}
class SimpleCoffee implements Coffee {
@Override
public double getCost() {
return 1;
}
@Override
public String getIngredients() {
return "Coffee";
}
}
我们令咖啡装饰器也继承 Coffee 接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
abstract class CoffeeDecorator implements Coffee {
protected final Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
decoratedCoffee = coffee;
}
/**
* 装饰器父类中直接转发"请求"至引用对象,也就是做简单的封装,维持原有对象的接口
*/
public double getCost() {
return decoratedCoffee.getCost();
}
public String getIngredients() {
return decoratedCoffee.getIngredients();
}
}
我们根据这个装饰器类再创建实体类. 其中的价格计算都是链式调用, 一层一层向内调用.
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
class WithMilk extends CoffeeDecorator {
public WithMilk(Coffee coffee) {
super(coffee);
}
@Override
public double getCost() {
double additionalCost = 0.5;
return super.getCost() + additionalCost;
}
@Override
public String getIngredients() {
String additionalIngredient = "milk";
return super.getIngredients() + ", " + additionalIngredient;
}
}
class WithSugar extends CoffeeDecorator {
public WithSugar(Coffee coffee) {
super(coffee);
}
@Override
public double getCost() {
return super.getCost() + 1;
}
@Override
public String getIngredients() {
return super.getIngredients() + ", Sugar";
}
}
最后客户端调用的方法如下.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Coffee c = new SimpleCoffee();
print(c);
//增加牛奶的咖啡
c = new WithMilk(c);
print(c);
//再加一点糖
c = new WithSugar(c);
print(c);
/*
花费了: 1.0
配料: Coffee
============
花费了: 1.5
配料: Coffee, milk
============
花费了: 2.5
配料: Coffee, milk, Sugar
============
*/