装饰器模式

1. 概念

1. 定义

在不改变原有对象的基础上,将功能附加到对象上

提供了比继承,更有弹性的替代方案(扩展原有对象功能)

类型:结构型

2 适用场景

  • 扩展一个类的功能,或者给一个类添加附加职责

  • 动态的给一个对象添加功能,这些功能可以再动态撤销

3 优缺点

优点:

  • 继承的有力补充,比继承灵活,不改变原有对象的情况下,给一个对象添加功能

  • 通过使用不同的装饰类以及这些装饰类的排列组合,可以实现不同的效果

  • 符合开闭原则。装饰者和被装饰者可以独立变化

缺点

  • 会出现更多的代码,更多的类,增加程序复杂性(各种抽象装饰类,抽象实体类)

  • 动态装饰时,多层装饰会更复杂

4 使用

  • 通常需要一个抽象的实体类,一个具体的实体类。一个抽象的装饰者,一个具体的装饰者。
  • 通常会将被装饰者,以参数的方式传给装饰者的构造器

2 代码

业务场景:烧烤店老板制作煎饼,有人加一个鸡蛋,一个肠。有人加两个鸡蛋一个肠

实体:煎饼

装饰者:鸡蛋,香肠

1
2
3
4
public abstract class ABattercake {
protected abstract String getDesc();
protected abstract int cost();
}
1
2
3
4
5
6
7
8
9
10
11
public class Battercake extends ABattercake {
@Override
protected String getDesc() {
return "煎饼";
}

@Override
protected int cost() {
return 8;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public abstract class AbstractDecorator extends ABattercake {
private ABattercake aBattercake;

public AbstractDecorator(ABattercake aBattercake) {
this.aBattercake = aBattercake;
}

// 在制作煎饼和香肠时需要的一些额外的操作
protected abstract void doSomething();

@Override
protected String getDesc() {
return this.aBattercake.getDesc();
}

@Override
protected int cost() {
return this.aBattercake.cost();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class EggDecorator extends AbstractDecorator {
public EggDecorator(ABattercake aBattercake) {
super(aBattercake);
}

@Override
protected void doSomething() {

}

@Override
protected String getDesc() {
return super.getDesc()+" 加一个鸡蛋";
}

@Override
protected int cost() {
return super.cost()+1;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class SausageDecorator extends AbstractDecorator{
public SausageDecorator(ABattercake aBattercake) {
super(aBattercake);
}

@Override
protected void doSomething() {

}

@Override
protected String getDesc() {
return super.getDesc()+" 加一根香肠";
}

@Override
protected int cost() {
return super.cost()+2;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Test {
public static void main(String[] args) {
ABattercake aBattercake;
aBattercake = new Battercake();
// 加一个鸡蛋
aBattercake = new EggDecorator(aBattercake);
// 加一个鸡蛋
aBattercake = new EggDecorator(aBattercake);
// 加一根香肠
aBattercake = new SausageDecorator(aBattercake);

System.out.println(aBattercake.getDesc()+" 销售价格:"+aBattercake.cost());

}
}

输出:煎饼 加一个鸡蛋 加一个鸡蛋 加一根香肠 销售价格:12


装饰器模式
http://example.com/装饰器模式/
作者
Panyurou
发布于
2023年10月3日
许可协议