简介
装饰器模式属于结构型模式,遵循开闭原则,合成复用原则。装饰器模式可以在不改变原类文件和继承的情况下扩展功能。
实现
刚好最近在选购耳机,就以耳机为例说明装饰器模式。首先,实现耳机接口,耳机是一对转换单元,它接接收播放器发出的电讯号,利用贴近耳朵的扬声器将其转化成音波,所以耳机应该具有接收和播放连个方法,如下:
public interface Earphones {
//接收电信号
void receive();
//播放声音
void play();
}
接着是具体的耳机实现类,一般我们可以简单的将耳机分为有线耳机和蓝牙耳机,下面以此创建两个实现耳机接口的具类WiredEarphones和BluetoothEarphones,如下:
//有线耳机
public class WiredEarphones implements Earphones {
@Override
public void receive() {
System.out.println("数据线接收");
}
@Override
public void play() {
System.out.println("播放声音");
}
}
//蓝牙耳机
public class BluetoothEarphones implements Earphones {
@Override
public void receive() {
System.out.println("蓝牙接收");
}
@Override
public void play() {
System.out.println("播放声音");
}
}
接着我们想要防水耳机且不管他是有线还是蓝牙,这是该怎么做?
首先不是所有的耳机都防水,所以在耳机接口Earphones添加防水方法就不太合适,那么一般此时我们会按照继承的思想创造防水有线耳机WaterproofWiredEarphones和防水蓝牙耳机WaterproofBluetoothEarphones,而在这里我们改用用装饰器模式实现防水耳机类WaterproofEarphones,如下:
public class WaterproofEarphones {
private Earphones earphones;
public WaterproofEarphones(Earphones earphones) {
this.earphones = earphones;
}
public void receive() {
earphones.receive();
System.out.println("防水");
}
public void play() {
earphones.play();
System.out.println("防水");
}
}
接下来我们在main方法中进行测试:
public class Main {
public static void main(String[] args) {
WaterproofEarphones bluetooth = new WaterproofEarphones(new BluetoothEarphones());
WaterproofEarphones wired = new WaterproofEarphones(new WiredEarphones());
bluetooth.receive();
wired.receive();
}
}
/******输出结果*****
* 蓝牙接收
* 防水
* 数据线接收
* 防水
*******************/
优点
- 装饰模式相比可以扩展类的功能,且比继承更加灵活
- 装饰模式可以根据不同的需求,进行不同的组合
缺点
- 虽然比继承更加灵活,但也更加复杂
实际应用
java中的FilterInputStream,BufferedInputStream,SynchronizedList等都是使用了装饰器模式。
网友评论