0%

装饰器模式

装饰器模式

装饰器模式可以动态的将责任附加到对象上,进行功能的扩展,不必改变原始的继承关系,通过创建包装对象来实现,其本质就是动态组合,比生成子类更为灵活

核心概念

  • Component 组件对象接口,恶意给这些对象动态地添加职责
  • ConcreteComponent 具体的组件对象
  • Decorator 所有装饰器的父类,需要定义一个与组件接口一致的接口,并持有一个Component对象
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
public abstract class Component {

public abstract void operation();
}

public class ConcreteComponent extends Component{
@Override
public void operation() {
System.out.println("-----");
}
}

public abstract class Decorator extends Component {

private Component component;

public Decorator(Component component){
this.component = component;
}

@Override
public void operation() {
component.operation();
}
}

public class ConcreteDecoratorA extends Decorator{

public ConcreteDecoratorA(Component component) {
super(component);
}

@Override
public void operation() {
super.operation();
addBehavior();
}

// 添加的职责
private void addBehavior(){
System.out.println("A");
}
}

public class ConcreteDecoratorB extends Decorator{

public ConcreteDecoratorB(Component component) {
super(component);
}

@Override
public void operation() {
super.operation();
addBehavior();
}

// 添加的职责
private void addBehavior(){
System.out.println("B");
}
}

如java io包中的设计就是使用了修饰者模式

1
2
3
4
5
6
7
8
9
10
11
12
13
public class BufferedInputStream extends FilterInputStream {

protected volatile InputStream in;

public BufferedInputStream(InputStream in) {
this(in, DEFAULT_BUFFER_SIZE);
}

}


BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));

优缺点

优点

  • 比使用继承更灵活,通过一种动态的方式来扩展一个对象的功能,在运行时可以选择不同的装饰器来实现不同的行为
  • 通过使用不同的具体装饰类以及这些修饰类的排列组合,可以创造出很多不同行为的组合,可以使用多个具体装饰类来装饰同一个对象,得到功能更强大的对象
  • 具体构件类与具体装饰类可以独立变化,是低耦合的
  • 更容易复用功能,把一系列复杂的功能分散到每个装饰器中,一般一个装饰器只实现一个功能,这样有利于装饰器功能的复用
  • 简化高层定义,可以通过组合装饰器的方式,为对象增加人一多的功能

缺点

  • 会产生很多的小对象,增加了系统的复杂性
  • 层次过多,排错需要逐级调试排查

使用场景

  • 需要扩展一个类的功能,或给一个类添加附加职责
  • 需要动态的给一个对象增加功能
  • 当不能采用生成子类的方式进行扩充时(如类定义为final的)
  • 在不影响其他对象的情况下,以动态、透明的方式给对象添加职责

欢迎关注我的其它发布渠道