设计模式源码git地址:design-pattern-src: 设计模式源码 (gitee.com)

该模式又称套娃模式

  1. 应用场景
  2. 场景举例
  3. Java实现

应用场景

大家都见过流中套娃的写法,类似如下

1
new BufferedInputStream(new FileInputStream(new File("")));

如类似的实现关系,如图

img

装饰者模式就是这样的写法,将对象动态增加功能,而不改变原有的功能

怎么体现不改变原有代码,而动态增加职责?

场景举例

目前有一个咖啡接口,可以有众多咖啡实现,比如星巴克,瑞幸,类图如下,这也是原始的代码

img

类代码如下

接口

1
2
3
public interface ICoffee {
void getCoffee();
}

星巴克

1
2
3
4
5
6
public class StarBucksCoffee implements ICoffee{
@Override
public void getCoffee() {
System.out.println("星巴克咖啡");
}
}

瑞幸

1
2
3
4
5
6
public class LukinCoffee implements  ICoffee {
@Override
public void getCoffee() {
System.out.println("瑞幸咖啡");
}
}

如果我现在打算在每种具体的咖啡加增加口味,如何进行修改?

有人说,那我直接在咖啡接口中增加一个加调味品的方法就行了,这好吗?这不好。违反了开闭原则(OCP原则)

新增一个装饰器类也去实现咖啡的方法,在之前父类制作咖啡的方法增加额外的方法,比如加糖,加牛奶。

img

Java实现

装饰器抽象类

1
2
3
4
5
6
7
8
9
10
public abstract class DecoratorSpice implements ICoffee{
private ICoffee coffee;
public DecoratorSpice(ICoffee coffee) {
this.coffee = coffee;
}
@Override
public void getCoffee() {
coffee.getCoffee();
}
}

加糖

1
2
3
4
5
6
7
8
9
10
11
public class SugarDecorator extends DecoratorSpice {
public SugarDecorator(ICoffee coffee) {
super(coffee);
}

@Override
public void getCoffee() {
super.getCoffee();
System.out.println("加糖");
}
}

加牛奶

1
2
3
4
5
6
7
8
9
10
11
12
public class MilkDecorator extends DecoratorSpice {

public MilkDecorator(ICoffee coffee) {
super(coffee);
}

@Override
public void getCoffee() {
super.getCoffee();
System.out.println("加牛奶");
}
}

调用

1
2
3
4
5
LukinCoffee lukinCoffee = new LukinCoffee();
MilkDecorator milkDecorator = new MilkDecorator(lukinCoffee);
SugarDecorator sugarDecorator = new SugarDecorator(milkDecorator);
MilkDecorator addMilk2 = new MilkDecorator(sugarDecorator);
addMilk2.getCoffee();

优点:可以看出在不改变源码的情况下,动态的增加了功能