装饰模式是指在不影响原有对象的情况下,动态地、无侵入地给一个对象添加一些额外的功能,如下这条 I/O 语句。
InpurStreamReader iReader = new InputStreamReader(new FileInputStream(new File("D:\abc.txt")));
如果把 D:\abc.txt 看作被装饰的对象,以上语句就依次对该对象进行了以下3步的包装。
new File("D:\abc.txt") 将字符串对象包装成了一个 File 对象,此时 File 对象包含了原字符串的内容。
new FileInputStream(...) 将 File 对象包装成了一个 FileinputStream 对象,此时 FileInputStream 包含了原 File 对象和原字符串的内容。
new InputStreamReader(...) 将 FileinputStream 对象包装成了一个 InputStreamReader 对象,此时 InputStreamReader 包含了原 FileInputStream 对象、原 File 对象和原字符串的内容。
可以发现,装饰模式可以让原对象经过一次次的包装,逐步拥有更强大的功能。因此在开发时,可以通过装饰模式对各个功能进行模块化封装。例如,如果要给对象 A 依次增加 X、Y 两个功能,就只需要对 A 进行两次包装即可。在 I/O 的设计中就大量使用到了这种装饰模式。
装饰模式包含了以下两个角色
1)抽象构建角色(Component)
被装饰对象的抽象接口。后续可以通过装饰者对该对象进行动态装饰。
2)具体构件角色(ConcreteComponent)
具体的对象,即抽象构建的一个实现类。
1)装饰角色(Decorator)
装饰抽象类,需要继承自 Component,用于装饰(扩展)Component 中定义的方法。语法上,装饰对象包含了一个对真实对象的引用。
2)具体装饰(ConcreteDecorator)角色:具体的装饰者,即装饰角色的一个实现类。
Phone 接口用于定义手机的基本功能是打电话call(),BasePhone 类是 Phone 的一个实现类,实现了 call() 定义的方法。SmallPhone 是 Phone 的一个装饰者,用于扩展 Phone 的功能。第一种装饰方式为 AISmartPhone,即给电话增加“人工智能”的功能;第二种装饰方式为 AutoSizeSmartPhone,即给电话增加“自动伸缩”的功能。
a 抽象构建角色(Component)
package decorator;
// 抽象构件角色(Component)
public interface Phone {
void call();
}
b 具体构建角色(ConcreteComponent)
package decorator;
// 具体构件角色(ConcreteComponent)
public class BasePhone implements Phone {
@Override
public void call() {
System.out.println("打电话");
}
}
c 装饰角色(Decorator)
package decorator;
// 装饰角色(Decorator)
public abstract class SmartPhone implements Phone {
private Phone phone;
public SmartPhone(Phone phone) {
super();
this.phone = phone;
}
@Override
public void call() {
phone.call();
}
}
d 第一个具体装饰角色(ConcreteDecorator)
package decorator;
public class AISmartPhone extends SmartPhone {
public AISmartPhone(Phone phone) {
super(phone);
}
// 给电话增加新的功能:人工智能
public void aiFunction() {
System.out.println("电话拥有人工智能的强大功能");
}
public void call() {
super.call();
aiFunction();
}
}
e 第一个具体装饰角色(ConcreteDecorator)
package decorator;
public class AutoSizeSmartPhone extends SmartPhone {
public AutoSizeSmartPhone(Phone phone) {
super(phone);
}
// 给电话增加新的功能:手机尺寸自动伸缩
public void autoSize() {
System.out.println("手机的尺寸可以自动伸缩");
}
public void call() {
super.call();
autoSize();
}
}
f 测试类
package decorator;
public class Test {
public static void main(String[] args) {
// 基础的电话功能
System.out.println("--基础的电话功能--");
BasePhone basePhone = new BasePhone();
basePhone.call();
// 进行 AISmartPhone 装饰后的电话
System.out.println("\n--智能手机:增加了AI的功能--");
AISmartPhone AISmartPhone = new AISmartPhone(basePhone);
AISmartPhone.call();
// 进行AutoSizeSmartPhone装饰后的电话
System.out.println("\n--智能手机:增加了自动伸缩的功能--");
AutoSizeSmartPhone autoSizeSmartPhone = new AutoSizeSmartPhone(basePhone);
autoSizeSmartPhone.call();
//进行AISmartPhone及AutoSizeSmartPhone两次装饰后的电话
System.out.println("\n--智能手机:增加了AI和自动伸缩的功能--");
SmartPhone smartPhone = new AutoSizeSmartPhone(new AISmartPhone(basePhone));
smartPhone.call();
}
}
--基础的电话功能--
打电话
--智能手机:增加了AI的功能--
打电话
电话拥有人工智能的强大功能
--智能手机:增加了自动伸缩的功能--
打电话
手机的尺寸可以自动伸缩
--智能手机:增加了AI和自动伸缩的功能--
打电话
电话拥有人工智能的强大功能
手机的尺寸可以自动伸缩
Process finished with exit code 0
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/chengqiuming/article/details/124774899
内容来源于网络,如有侵权,请联系作者删除!