学会设计模式,你就可以像拥有魔法一样,在开发过程中解决一些复杂的问题。设计模式是由经验丰富的开发者们(GoF)凝聚出来的最佳实践,可以提高代码的可读性、可维护性和可重用性,从而让我们的开发效率更高。通过不断的练习和实践,掌握其中的奥妙,选择合适的设计模式,能为我们的项目增加一丝神奇的魔力。
概念:
不改变现有对象结构的同时给它添加一些额外的功能。就增加对象功能来说,装饰模式比生成子类实现更为灵活。
实例:
随着手机的升级,手机不仅仅是用来打电话,发短信的工具,它也可以作为照相机,nfc刷卡等
目的:
手机现有功能正常的情况下,保证可拓展性
适用场景:
动态拓展或撤销类的功能
优点:
将装饰类和被装饰类解耦
弊端:
增加代码复杂度
类图:
框架用到的地方:
Java I/O 的设计框架便是使用的 装饰者模式。BufferedInputStream(透明的装饰模式)、DataInputStream(半透明装饰模式)
Coding:
Phone
public interface Phone {
void doSomething();
}
Dumbphone
public class Dumbphone implements Phone{
@Override
public void doSomething() {
System.out.println("老年机功能:");
System.out.println("打电话");
System.out.println("发短信");
}
}
PhoneDecorator(Phone装饰器)
public interface PhoneDecorator extends Phone {
public void doOtherthing();
}
通过对接口Phone的继承并添加了新的功能方法(doOtherthing):
Smartphone
public class Smartphone implements PhoneDecorator {
private Phone phone;
public Smartphone(Phone phone) {
this.phone = phone;
}
@Override
public void doSomething() {
phone.doSomething();
}
@Override
public void doOtherthing() {
phone.doSomething();
System.out.println("智能手机通过装饰器添加了:");
System.out.println("拍照");
System.out.println("NFC");
}
}
MiPhone
public class MiPhone implements PhoneDecorator {
private Phone phone;
public MiPhone(Phone phone) {
this.phone = phone;
}
@Override
public void doSomething() {
phone.doSomething();
}
@Override
public void doOtherthing() {
phone.doSomething();
System.out.println("MiPhone通过装饰器添加了:");
System.out.println("拍照");
System.out.println("NFC");
System.out.println("红外遥控器");
}
}
测试
public static void main(String[] args) {
System.out.println("======智能手机=======");
new Smartphone(new Dumbphone()).doOtherthing();
System.out.println("======MiPhone=======");
new MiPhone(new Dumbphone()).doOtherthing();
}
测试结果
======智能手机=======
老年机功能:
打电话
发短信
智能手机通过装饰器添加了:
拍照
NFC
======MiPhone=======
老年机功能:
打电话
发短信
MiPhone通过装饰器添加了:
拍照
NFC
红外遥控器
装饰器模式可以分为:半透明装饰模式、透明装饰模式
小名上面的demo属于为原有对象添加“新功能”的装饰(doOtherthing),称之为半透明装饰模式,反之如果装饰器没有为原来的对象添加“新功能”,而是只实现不同的doSomething(),这就被称之为透明装饰模式。
就如Java I/O 框架中的BufferedInputStream并没有在InputStream之外添加新的方法,所以它属于透明装饰模式;
DataInputStream中新增了 readInt、readLong 等方法,所以 DataInputStream 属于半透明装饰模式。