Zer0e's Blog

设计模式之装饰器模式

字数统计: 833阅读时长: 3 min
2020/08/17 Share

前言

继续讲讲装饰器模式。

正文

概念

装饰器模式就是向一个现有对象添加新的功能,又不改变原对象的结构。它属于结构型模式,因为是对现有类进行包装,所以称作装饰器模式。
这么一说,装饰器模式与代理模式有点类似?都可以拓展一个类的功能,又不改变原对象。他们之间的差别之后会说。
那这个模式具体的使用场景就是扩展类的功能,并且可以动态修改。

实现

我们来实现一个简单的装饰器模式。
这里我们先创建接口Component,规范具体实现类与装饰类。

1
2
3
public interface Component {
public void doAction();
}

接着是具体实现类

1
2
3
4
5
6
public class ConcreteComponent implements Component{
@Override
public void doAction() {
System.out.println("执行操作");
}
}

创建抽象装饰类

1
2
3
4
5
6
7
8
9
10
11
12
public abstract class Decorator implements Component{
protected Component component;

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

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

然后是具体装饰类

1
2
3
4
5
6
7
8
9
10
11
12
public class ConcreteDecorator extends Decorator{
public ConcreteDecorator(Component component) {
super(component);
}

@Override
public void doAction() {
super.doAction();
// 这里写其他功能,如记录
System.out.println("执行额外功能");
}
}

我们编写客户端调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Client {
public static void main(String[] args) {
Component component = new ConcreteComponent();
Decorator decorator = new ConcreteDecorator(component);

// 普通类执行
component.doAction();

System.out.println();
// 使用装饰类执行
decorator.doAction();
}
}

/*
执行操作

执行操作
执行额外功能
*/

小结

装饰器模式中的抽象装饰器与具体被装饰的类都要实现同一个接口,客户端的请求通过装饰类,装饰类通过具体类来实现,层层传递。在装饰类中能扩展具体类的功能。

与代理模式的异同

装饰器模式也是添加中间层,来实现扩展,但是与代理模式不同的是,代理模式可以隐藏具体类的实现,具体类对于客户端来说是不可见的。而装饰器模式中具体类是可以在客户端中生成的,并且装饰类必须传入具体类才能实现装饰。
这是两者的异同点。

半透明的装饰模式

在上面的装饰模式中,具体类,装饰类的接口与抽象接口类Component的接口完全一致。这种称作透明的装饰模式。而如果装饰类的接口与抽象接口类的接口不一致,那装饰器就会变成适配器模式。但这种装饰模式是可以接受的,称作半透明的装饰器模式。
即全透明的装饰器模式增强功能不改变接口,半透明的装饰器模式增强功能,改变接口,而适配器模式则是不改变功能,改变接口。
将在下一篇讲讲适配器模式。

优缺点

最后来讲讲优缺点,装饰器模式优点很明显,就是扩展类的功能,它是继承的一个替代方式,而缺点在于如果存在多层装饰就会十分繁琐,对问题的查找较为麻烦。

后言

这篇文章讲了装饰器模式的概念与实现,下一篇大概会讲讲适配器模式。

CATALOG
  1. 1. 前言
  2. 2. 正文
    1. 2.1. 概念
    2. 2.2. 实现
    3. 2.3. 小结
    4. 2.4. 与代理模式的异同
    5. 2.5. 半透明的装饰模式
    6. 2.6. 优缺点
  3. 3. 后言