一、引言
装饰模式是什么?为什么有装饰模式?装饰模式怎么实现?
- 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的职责,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
- 装饰模式就是用来给一个已有的类添加额外的功能。
二、实现方式
我们先来看一个需求: 简单的手机(SimplePhone)在接收来电的时候会发出声音来提醒主人;现在要将该手机升级(1)先升级为带振动的手机(JarPhone),使得手机在接收来电不仅有声音,还有振动。(2)再升级为灯光手机(ComplexPhone) ,使得来电不仅有声音,振动,还有灯光提醒。
这个需求相当于在原有的手机上不断新增功能,因此可以用到装饰模式。 先上类图: 由图可以看出,我们要为手机添加新的功能,于是写了一个手机装饰类(抽象),然后要新增什么功能的手机,继承与他就好了。 而新功能的手机和原来的则是组合关系,毕竟要拿原来的手机进行升级嘛。 下面看代码实现:
/**
* 手机接口
*/
public interface Phone {
//接听方法
public void call();
}
/**
* 简单手机
*/
public class SimplePhone implements Phone {
public void call() {
System.out.println("响铃");
}
}
/**
* 手机装饰类,抽象
*/
public abstract class PhoneDecorator implements Phone{
protected Phone phone;//组合了一个准备要升级的手机
public PhoneDecorator(Phone phone) {
this.phone = phone;
}
public abstract void call();
}
public class JarPhone extends PhoneDecorator {
public JarPhone(Phone phone) {
super(phone);
}
public void call() {
//调用原来手机的接听
phone.call();
//新增振动功能
System.out.println("振动");
}
}
public class ComplexPhone extends PhoneDecorator {
public ComplexPhone(Phone phone) {
super(phone);
}
public void call() {
//调用原来手机的接听
phone.call();
//新增灯光功能
System.out.println("灯光");
}
}
public static void main(String[] args) {
SimplePhone phone = new SimplePhone();
System.out.println("-------------简单手机接听------------------");
phone.call();
System.out.println("-------------升级为带振动手机接听------------------");
JarPhone jarPhone = new JarPhone(phone);
jarPhone.call();
System.out.println("-------------升级为带振动+灯光手机接听------------------");
ComplexPhone complexPhone = new ComplexPhone(jarPhone);
complexPhone.call();
}
下面是运行结果: 由结果可知,我们在没动原来手机的情况下,对它进行了改造,增加了一些新的功能,这就是装饰模式。
三、结束
装饰模式相对简单,本意就是在不动原来类的情况下新增功能,满足开闭原则。