一、核心作用:
- 动态的为一个对象增加新功能
- 装饰模式是一种代理继承是技术,无需通过继承增加子类就可以扩展对象
- 使用对象关联关系代理继承关系,更加灵活,避免类型体系快速膨胀
- 装饰模式降低系统的耦合度,可以动态的增加或删除对象
- 使需要装饰的具体构建类和具体修饰类可以独立变化,以便增加新的具体构建类和具体装饰类
二、常见应用场景:
1、IO输入流/IO输出流
2、Servlet API reques对象
三、装饰模式角色分类:
- Component抽象构建:真实对象和装饰对象有相同的接口,这样客户端对象就可以以与真实对象相同的方式同装饰对象交互
- ConcreteComponent具体构建角色(真实角色)
- Decorator装饰角色:持有一个抽象构建的引用,装饰对象接受客户端的请求,并把这些请求转发给真实对象,这样可以在真实对象调用前后增加新功能
- ConcreteDecorator具体装饰角色:负责给构建对象增加新的责任
四、IO流实现细节:
Component抽象构建:
io流中的InputStream、OutputStream、Reader、Writer
ConcreteComponent 具体构建角色(真实角色):
FileInputStream、FileOutputStream
Decorator装饰角色:
持有一个抽象构建的引用:FilterInputStream、FilterOutputStream
ConceteDecorator具体修饰角色:
负责给构建对象增加新责任:BufferedOutputStream、BufferedInputStream
五、代码示例:
一、Conponent抽象部件:
package com.hezeu.decorator;
/**
* @Classname ICar
* @Description 抽象构建
* @Date 2020/2/23 下午 06:01
* @Created by 朱进博 1724282894@qq.com
*/
public interface ICar {
void move();
}
二、ConcreteConponent具体构建部件(真实角色):
/**
* 具体构建角色(真实对象)
*/
class Car implements ICar{
@Override
public void move() {
System.out.println("在陆地上跑");
}
}
三、Decorator装饰角色:
/**
* 装饰角色
*/
class SuperCar implements ICar{
protected ICar car;
public SuperCar(ICar car) {
this.car = car;
}
@Override
public void move() {
car.move();
}
}
四、ConcreteDecorator 具体修饰角色:
/**
* 具体修饰角色
*/
class FlyCar extends SuperCar{
public FlyCar(ICar car) {
super(car);
}
public void fly(){
System.out.println("天上飞");
}
@Override
public void move() {
super.move();
fly();
}
}
四、Client类测试:
package com.hezeu.decorator;
/**
* @Classname Client
* @Description TODO
* @Date 2020/2/23 下午 06:15
* @Created by 朱进博 1724282894@qq.com
*/
public class Client {
public static void main(String[] args) {
Car car = new Car();
car.move();
System.out.println("------增加新功能天上飞---");
SuperCar flycar = new FlyCar(car);
flycar.move();
System.out.println("------增加新功能天上飞水里游-----");
SuperCar waterCar = new WaterCar(flycar);
waterCar.move();
}
}
结果如下:
六、装饰模式的优缺点:
优点:
扩展对象功能,比继承灵活,不会导致类的数量急剧增加
可以对一个对象进行一个多次装饰,创造出不同的行为组合,得到更强大的功能
具体构建类的具体装饰可以独立变化,用户根据自己需求去增加新的具体构建子类和具体装饰子类
缺点:
产生很多小对象,大量小对象占据内存,一定程度上影响性能。
装饰模式易出错,调试排查比较麻烦
七、装饰模式与桥接模式的区别:
两个模式均为解决过多子类对象的问题,但是桥接模式是对象自身现有机制沿着多维度变化。装饰模式是为了增加新的功能。
感谢阅读,水平有限,如有错漏,还请不吝赐教