文章首发:
结构型模式:装饰模式java
七大结构型模式之四:装饰模式。设计模式
姓名 :装饰模式微信
英文名 :Decorator Pattern架构
价值观 :人靠衣装,类靠装饰机器学习
我的介绍 :
Attach additional responsibilities to an object dynamically keeping the same interface. Decorators provide a flexible alternative to subclassing for extending functionality.
动态地给一个对象添加一些额外的职责。就增长功能来讲,装饰模式相比生成子类更为灵活。
(来自《设计模式之禅》)ide
夏天到了,吃货们期待的各类各样冷冻零食就要大面积面向市场,什么冰淇淋、雪糕、冰棍等等。今天的装饰模式不讲这些都受欢迎的零食,讲讲那乌黑滴龟苓膏。不知道大伙们喜不喜欢吃龟苓膏,我是挺喜欢的,不喜欢的人不少都闲它苦,应该没有人愿意在没加任何糖类的状况下吃龟苓膏。不少糖水店会提供几种龟苓膏,好比蜂蜜龟苓膏、牛奶龟苓膏。下面咱们空想出一个场景来。学习
天气到了 30℃,小明和小红加班到了 10 点,一块儿下班,路过一家糖水店,小红萌生了吃糖水解解热的想法,小明最近涨薪,就提出要请小红吃糖水,他们进去糖水店,小红想着很久没吃龟苓膏了,就想吃吃,怀念一下童年那段在农村夜晚吃龟苓膏的时光。糖水店里面有 3 种龟苓膏,一种是普通龟苓膏(这老板竟然提供不加任何糖分的,过度了),一种是蜂蜜龟苓膏,另一种是牛奶龟苓膏,小明点了一份蜂蜜龟苓膏,小红想加蜂蜜和牛奶,就咨询了老板娘,可否同时加蜂蜜和牛奶,老板娘用那东北腔爽快地回复小红:行。小明和小红就等龟苓膏上桌。。。脑洞到这。测试
咱们来把这个故事套入到装饰模式里去。上面故事里老板卖 3 种龟苓膏,而都不知足小红的需求,小红想要的是蜂蜜牛奶龟苓膏,若是用继承来实现龟苓膏,那就没法知足小红的要求了,由于继承直接固定了龟苓膏的作法,加什么就是什么,要蜂蜜牛奶龟苓膏,那就须要另一个龟苓膏类表明蜂蜜牛奶龟苓膏;而用装饰模式则不一样,下面看看装饰模式的实现代码。flex
龟苓膏抽象类,该类定义了制做龟苓膏的抽象方法。this
/** * 龟苓膏 */ 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(); } } 打印结果: 盛一碗龟苓膏 加蜂蜜 盛一碗龟苓膏 加蜂蜜 加牛奶
咱们看到,小明的龟苓膏只加蜂蜜,小红的龟苓膏加了蜂蜜和牛奶,这样就很简单的知足了小红的要求。
装饰模式在一些类与类之间有叠加效应(也就是给一个类增长附加功能)的场景中很是好用,它能够说是继承的替代品,有更好的扩展性,也比较灵活。在 Java JDK 源码中也大面积用到了装饰模式,好比:java.io.BufferedInputStream(InputStream)。学完基础知识后,能够看看源码中是怎么实现的,巩固知识。
推荐阅读
公众号后台回复『大礼包』获取 Java、Python、IOS 等教程
加我的微信备注『教程』获取架构师、机器学习等教程