目录
1.简介
装饰模式是结构型设计模式之一
定义:
动态地给一个对象添加一些额外的功能,比生成子类要灵活。就增加对象功能来说,装饰模式比生成子类实现更为灵活,是一个对象结构型模式。可以在不需要创建更多子类的情况下,让对象的功能得以扩展
使用场景:
需要透明且动态地拓展类的功能的场景。
所以装饰模式所采用的方法就是利用关联代替继承,这样一来降低继承所导致的耦合度增大,同时,软件维护上,关联关系的松耦合性,使得系统更加的容易维护。树形的层数较少,在于横向的拓展,拓展起来更加方便,还能够很好的实现运行时动态拓展。
/**
* 龟苓膏
*/
abstract class HerbalJelly {
/**
* 制作龟苓膏方法
*/
public abstract void process();
}
老板提供的最基本的龟苓膏,这种龟苓膏不加任何料,就是那苦苦的龟苓膏,我们称它为普通龟苓膏。
/**
* 普通龟苓膏
*/
class CommonHerbalJelly extends HerbalJelly {
@Override
public void process() {
System.out.println("盛一碗龟苓膏");
}
}
另外 2 种龟苓膏:蜂蜜龟苓膏和牛奶龟苓膏,不是用继承实现,而是用装饰器实现,我们可以发现这 2 种龟苓膏都是基于上面普通龟苓膏添加不同的糖类食品制作而成。下面实现一个抽象类充当装饰器。
/**
* 龟苓膏装饰器
*/
abstract class Decorator extends HerbalJelly {
private HerbalJelly herbalJelly;
public Decorator(HerbalJelly herbalJelly) {
this.herbalJelly = herbalJelly;
}
@Override
public void process() {
this.herbalJelly.process();
}
}
接下来就根据上面的龟苓膏装饰器来实现蜂蜜龟苓膏和牛奶龟苓膏。
/**
* 蜂蜜龟苓膏
*/
class HoneyHerbalJelly extends Decorator{
public HoneyHerbalJelly(HerbalJelly herbalJelly) {
super(herbalJelly);
}
@Override
public void process() {
super.process();
System.out.println("加蜂蜜");
}
}
/**
* 牛奶龟苓膏
*/
class MilkHerbalJelly extends Decorator{
public MilkHerbalJelly(HerbalJelly herbalJelly) {
super(herbalJelly);
}
@Override
public void process() {
super.process();
System.out.println("加牛奶");
}
}
下面提供我们的测试代码,还记得上面说的,小明要了一碗蜂蜜龟苓膏,小红则要了一碗蜂蜜牛奶龟苓膏。
public class DecoratorTest {
public static void main(String[] args) {
CommonHerbalJelly commonHerbalJelly = new CommonHerbalJelly();
HoneyHerbalJelly honeyHerbalJelly = new HoneyHerbalJelly(commonHerbalJelly);
// 小明的蜂蜜龟苓膏
honeyHerbalJelly.process();
MilkHerbalJelly milkHerbalJelly = new MilkHerbalJelly(honeyHerbalJelly);
// 小红的蜂蜜牛奶龟苓膏
milkHerbalJelly.process();
}
}
打印结果:
盛一碗龟苓膏
加蜂蜜
盛一碗龟苓膏
加蜂蜜
加牛奶
我们看到,小明的龟苓膏只加蜂蜜,小红的龟苓膏加了蜂蜜和牛奶,这样就很简单的满足了小红的要求。
2.总结
装饰模式在一些类与类之间有叠加效应(也就是给一个类增加附加功能)的场景中非常好用,它可以说是继承的替代品,有更好的扩展性,也比较灵活。在 Java JDK 源码中也大面积用到了装饰模式,比如:java.io.BufferedInputStream(InputStream)。学完基础知识后,可以看看源码中是怎么实现的,巩固知识。
装饰模式动态地给一个对象添加一些额外的功能,相对于继承的方式,更加灵活。
装饰模式经常被误认为是代理模式。装饰模式是以对客户透明的方式扩展对象的功能,是继承关系的一个替代方案。而代理模式则是给一个对象提供一个代理对象,并由代理对象来控制原有对象的引用。
前者重在增加功能,后者重在对代理对象施加控制,不是对对象本身功能的增强。
参考链接:https://blog.csdn.net/SEU_Calvin/article/details/71138079