乐趣区

关于java:别再写满屏的爆爆爆炸类了试试装饰器模式这才是优雅的方式

背景

你还在写满屏的爆炸类吗?

就是不管三七二十一,把所有代码写在一个类外面,这样代码不优雅不说,如果改变波及到老代码,可能还会影响线上的零碎稳定性。

其实,很多状况,咱们奇妙地利用设计模式就能解决很多潜在的零碎问题,明天栈长就教大家应用装璜器模式,在不改变老代码的前提下扩大性能,岂但能晋升代码优雅性,还能不影响现有的性能,谁用谁晓得,真香!!

什么是装璜器模式?

装璜器模式,从字面上了解,顾名思义,就是一种装璜模式,它能够在不改变原有代码的状况下,对现有的对象、行为进行新的档次的包装、装璜,加强原有的基本功能以提供更丰盛的能力。

举个简略的装修的小例子:

清理 > 刮腻子 > 涂油漆 > 挂壁画

也能够是:

清理 > 刮腻子 > 贴大理石 > 挂电视

或者能够是:

清理 > 刮腻子 > 贴墙纸

这是一步步的简略装修墙面过程(哈哈,大略如此,我不是业余的),这就是装璜器模式,装璜的每个步骤互不干涉,但前面的步骤须要依赖前一个步骤的实现,前面的步骤能够一直在前一个的装璜根底上进行减少。

装璜器模式结构图如下:

装璜器模式类构造如下:

  • Component:组件接口类,定义被装璜类的基本功能
  • ConcreteComponent:组件接口的根本实现类
  • Decorator:装璜器角色类,实现并持有一个 Component 对象实例
  • ConcreteDecorator:装璜器的实现类

装璜器模式的长处:

1、不改变原有代码,动静减少性能;

2、对象之间不会相互依赖,松耦合,够优雅;

3、合乎开闭准则,扩展性好、便于保护;

装璜器模式的毛病:

1、装璜环节如果很多的话,会造成装璜器类收缩;

2、装璜器层层嵌套比较复杂,使用者必须分明所有的装璜器类及其用处;

装璜器模式实战

咱们把下面的装修的案例用装璜器模式实现一下。

组件接口类:

/**
 * 墙面装修接口
 * @author: 栈长
 * @from: 公众号 Java 技术栈
 */
public interface WallBeautify {

    /**
     * 装修操作
     * @author: 栈长
     * @from: 公众号 Java 技术栈
     */
    void operation();}

组件接口的根本实现类:

/**
 * 墙面装修根本实现(清理墙面)* @author: 栈长
 * @from: 公众号 Java 技术栈
 */
public class WallBeautifyClean implements WallBeautify {

    @Override
    public void operation() {System.out.println("开始清理墙面");
    }

}

装璜器角色类:

这是一个抽象类,实现并持有一个 Component 对象实例,这里应用的是聚合,而不是继承,这也是装璜器模式的要点所在。

/**
 * 墙面装修装璜器角色
 * @author: 栈长
 * @from: 公众号 Java 技术栈
 */
public abstract class WallBeautifyDecorator implements WallBeautify {

    /**
     * 持有一个 Component 对象实例
     * @author: 栈长
     * @from: 公众号 Java 技术栈
     */
    private WallBeautify wallBeautify;

    public WallBeautifyDecorator(WallBeautify wallBeautify) {this.wallBeautify = wallBeautify;}

    @Override
    public void operation() {wallBeautify.operation();
        decoration();}

    /**
     * 装璜器实现类自定义实现办法
     * @author: 栈长
     * @from: 公众号 Java 技术栈
     */
    public abstract void decoration();}

覆写原操作方法,在原操作之后再进行装璜,所以须要提供一个形象的 decoration 办法供不同的装璜器的实现类去实现。

装璜器的实现类:

这里定义了 3 个装修过程:

刮腻子 > 涂油漆 > 挂壁画

所以各自去继承 装璜器角色类 并实现其装璜办法:

/**
 * 墙面装修装璜器角色实现(刮腻子)* @author: 栈长
 * @from: 公众号 Java 技术栈
 */
public class WallBeautifyPutty extends WallBeautifyDecorator {public WallBeautifyPutty(WallBeautify wallBeautify) {super(wallBeautify);
    }

    @Override
    public void decoration() {System.out.println("开始刮腻子");
    }

}
/**
 * 墙面装修装璜器角色实现(涂油漆)* @author: 栈长
 * @from: 公众号 Java 技术栈
 */
public class WallBeautifyPaint extends WallBeautifyDecorator {public WallBeautifyPaint(WallBeautify wallBeautify) {super(wallBeautify);
    }

    @Override
    public void decoration() {System.out.println("开始涂油漆");
    }

}
/**
 * 墙面装修装璜器角色实现(挂壁画)* @author: 栈长
 * @from: 公众号 Java 技术栈
 */
public class WallBeautifyHang extends WallBeautifyDecorator {public WallBeautifyHang(WallBeautify wallBeautify) {super(wallBeautify);
    }

    @Override
    public void decoration() {System.out.println("开始挂壁画");
    }

}

测试一下:

/**
 * 装璜器模式测试类
 * @author: 栈长
 * @from: 公众号 Java 技术栈
 */
public class DecoratorTest {public static void main(String[] args) {
        // 清理墙面
        WallBeautify wallBeautifyClean = new WallBeautifyClean();
        wallBeautifyClean.operation();
        System.out.println("--------------");

        // 刮腻子
        WallBeautify wallBeautifyPutty = new WallBeautifyPutty(wallBeautifyClean);
        wallBeautifyPutty.operation();
        System.out.println("--------------");

        // 涂油漆
        WallBeautify wallBeautifyPaint = new WallBeautifyPaint(wallBeautifyPutty);
        wallBeautifyPaint.operation();
        System.out.println("--------------");

        // 挂壁画
        WallBeautify wallBeautifyHang = new WallBeautifyHang(wallBeautifyPaint);
        wallBeautifyHang.operation();
        System.out.println("--------------");

        // 多层嵌套
        WallBeautify wbh = new WallBeautifyHang(new WallBeautifyPaint(new WallBeautifyPutty(new WallBeautifyClean())));
        wbh.operation();
        System.out.println("--------------");
    }

}

本节教程所有实战源码已上传到这个仓库:

https://github.com/javastacks…

输入后果:

 开始清理墙面
--------------
开始清理墙面
开始刮腻子
--------------
开始清理墙面
开始刮腻子
开始涂油漆
--------------
开始清理墙面
开始刮腻子
开始涂油漆
开始挂壁画
--------------
开始清理墙面
开始刮腻子
开始涂油漆
开始挂壁画
--------------

后果输入失常!

能够看到,装璜器模式的应用还是绝对比较简单的,应用装璜器模式能够达到不同的装璜成果,这样即满足了不同客户的需要,而又不必改变原有的代码,还是挺香的。

后续《 设计模式 》系列文章在公众号 Java 技术栈陆续更新中,请大家继续关注哦!

装璜器模式在 JDK 中的利用

当初咱们晓得如何应用装璜器模式了,当初咱们再看看 JDK 哪些地方使用了装璜器模式呢。

1、IO 流

最经典的装璜器模式利用莫过于 JDK 中的 IO 流了(InputStream/ OutputStream)

罕用的 InputStream 类构造类如下:

InputStream 和 FileInputStream 是根本的组件接口和实现。

FilterInputStream 就是一个实现组件接口并持有实例援用的装璜器角色:

BufferedInputStream、DataInputStream 都是不同的 FilterInputStream 的装璜实现。

OutputStream 也是同样的原理。

2、同步汇合

要对非线程平安的汇合(如:List、Set)简略提供线程平安的性能,应用装璜器模式也能轻松实现。

来看同步汇合工具类办法:

java.util.Collections#synchronizedList(List)

java.util.Collections#synchronizedSet(Set)

它们都是 SynchronizedCollection 的装璜器实现类:

SynchronizedCollection 是装璜器角色:

SynchronizedCollection 实现了汇合组件接口并持有汇合实例援用,而 Collection(List)和 ArrayList 是根本的组件接口和实现。

总结

本文介绍了装璜器模式的基本概念,也做了一个根本实战,并且举了两个 JDK 中的装璜器模式的例子,置信大家对装璜器模式有了一个根本意识了,怎么使用到我的项目中,大家应该有谱了吧?

当然,设计模式只是给大家一个设计的参考,并不能自觉使用,否则事与愿违。话说,你是怎么在我的项目中利用装璜器模式的呢?欢送留言分享案例!

本节教程所有实战源码已上传到这个仓库:

https://github.com/javastacks…

好了,明天的分享就到这里了,前面栈长我会更新其余设计模式的实战文章,公众号 Java 技术栈第一工夫推送。Java 技术栈《 设计模式 》系列文章陆续更新中,请大家继续关注哦!

最初,感觉我的文章对你用播种的话,动动小手,给个在看、转发,原创不易,栈长须要你的激励。

版权申明: 本文系公众号 “Java 技术栈 ” 原创,转载、援用本文内容请注明出处,剽窃、洗稿一律投诉侵权,后果自负,并保留追究其法律责任的权力。

近期热文举荐:

1.1,000+ 道 Java 面试题及答案整顿 (2022 最新版)

2. 劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4.20w 程序员红包封面,快快支付。。。

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

退出移动版