当前位置: 首页 > news >正文

Java设计模式--装饰器模式到Java IO 流

装饰器模式

抽象构件角色:给出一个抽象接口,以规范准备接受附加责任的对象。

具体构件角色:定义准备接受附加责任的对象。

抽象装饰角色:持有一个构件对象的实例,并对应一个与抽象构件接口一致的接口。

具体装饰角色:负责给具体构件加上额外的责任。

什么时候使用:

1. 需要扩展一个类的功能,或者给一个类增加附加责任。

2. 需要动态的给一个对象增加功能,这些功能可以再动态的撤销。

3. 需要增加由一些基本功能的排列组合而产生的的大量的功能,从而使继承关系变得不现实。

我以给汽车换颜色为例:

汽车厂生产汽车实例,4S店可以喷漆换颜色。

Car接口:

/**
 * Created by 001977 on 2019-04-12 11:39.
 * 抽象构件角色
 */
public interface Car {

    /**
     * 出厂车身颜色
     */
    void skin();
}

 

具体构件卡罗拉:

/**
 * Created by 001977 on 2019-04-12 11:42.
 * 具体构件:COROLLA卡罗拉(灰色)
 */
public class Corolla implements Car {

    @Override
    public void skin() {
        System.out.println("超级无敌灰色");
    }
}

 

4S店抽象装饰器:

/**
 * Created by 001977 on 2019-04-12 11:45.
 * 抽象装饰角色(4S店)
 */
public abstract class FourS implements Car {

    private Car car;

    public FourS(Car car) {
        this.car = car;
    }

    @Override
    public void skin() {
        car.skin();
    }
}

 

具体装饰器:喷枪红

/**
 * Created by 001977 on 2019-04-12 11:49.
 * 具体装饰角色(红色喷漆)
 */
public class RedSprayPaint extends FourS {

    public RedSprayPaint(Car car) {
        super(car);
    }

    @Override
    public void skin() {
        super.skin();
        System.out.println("花2000块钱喷红色的漆");
    }
}

 

具体装饰器:喷枪白

/**
 * Created by 001977 on 2019-04-12 11:49.
 * 具体装饰角色(白色喷漆)
 */
public class WhiteSprayPaint extends FourS {

    public WhiteSprayPaint(Car car) {
        super(car);
    }

    @Override
    public void skin() {
        super.skin();
        System.out.println("花1000块钱喷白色的漆");
    }
}

 

测试运行:

public class Main {
    public static void main(String[] args) throws IOException {
        System.out.println("====================出厂颜色====================");
        Car corolla = new Corolla();
        corolla.skin();
        System.out.println("====================换颜色====================");
        RedSprayPaint red = new RedSprayPaint(new WhiteSprayPaint(corolla));
        red.skin();
    }
}

 

 

IO中的体现(以InputStream为例)

抽象构件角色:由InputStream扮演,这个抽象类为各种子类型流处理器提供统一的接口。

具体构件角色:由FileInputStream、ObjectInputStream 、ByteArrayInputStream 等原始流处理器扮演,他们实现了InputStream的接口,可以被装饰器装饰。

抽象装饰角色:由FilterInputStream扮演,他也实现了InputStream的接口。

具体装饰角色:由DataInputStream 、BufferedInputStream等扮演。

..

由于IO库中需要很多性能的各种组合,如果用继承方法实现,那么每一种组合都需要一个类,这样会造成大量性能重复的类出现。如果使用装饰器模式,那么类的数目大大减少,性能的重复也减到最少。因此装饰器模式是IO中的基本模式。

以InputStream【抽象构件】为例:上图中的流可以分为两类:原始流处理器【具体构件】(FileInputStream及其左边的类)和链接流处理器【装饰器】(实现FilterInputStream的类【具体装饰器】)。

首先InputStream定义了一些规范:

接着比如FileInputStream去实现,实际上它都是去调用本地方法的,请看:

然后装饰器也去实现InputStream的方法,关键是持有InputStream对象的实例

 

最后具体的装饰器比如:

BufferedInputStream装饰了InputStream的内部工作方式,使得流的读入操作使用缓冲机制,不会对每一次流读入的操作都产生一次物理读盘动作,从而提高了程序的效率。它的内部有个buf字节数组用来缓存数据。

读取的时候调用fill方法,简单来说就是先尝试获取缓冲区,然后再操作输入流将数据读入缓冲区,这期间还有一些细节比如调整pos不再赘述。

还有DataInputStream提供了一些直接读取某种类型的数据的方法,省的我们读取完再去做转换。

比如:readBoolean

它的读入操作read方法就是直接调用原始流处理器的方法,并不复杂

 最后附上一张画了一天的IO继承关系图:

 如果图片看不清,鼠标右键---在新标签页下打开图片

转载于:https://www.cnblogs.com/LUA123/p/10685693.html

相关文章:

  • 【iOS工具】快速上传ipa文件到iTunes Connect
  • 使用DataWorks调度DLA循环任务
  • postgresql行列转换函数
  • SQL中IF和CASE语句
  • Python Day3
  • [20190416]完善shared latch测试脚本2.txt
  • Windows下如何更新 node.js
  • 美团数据调优指北【转载】
  • 如何给列表降维?sum()函数的妙用
  • 好程序员分享JQuery.get提交页面不跳转的解决方法
  • QT 栅格布局
  • 如何根据业务封装自己的功能组件
  • 心理学解析一见钟情的感觉
  • 深入理解nvme hardware queue pair
  • 家具建材行业电商平台解决方案
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • Promise面试题2实现异步串行执行
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • SwizzleMethod 黑魔法
  • 从setTimeout-setInterval看JS线程
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 分布式任务队列Celery
  • 关于for循环的简单归纳
  • 简单实现一个textarea自适应高度
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 线性表及其算法(java实现)
  • 如何正确理解,内页权重高于首页?
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • ​Java并发新构件之Exchanger
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • #、%和$符号在OGNL表达式中经常出现
  • #ubuntu# #git# repository git config --global --add safe.directory
  • (js)循环条件满足时终止循环
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (板子)A* astar算法,AcWing第k短路+八数码 带注释
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (力扣)循环队列的实现与详解(C语言)
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (转)http-server应用
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .chm格式文件如何阅读
  • .NET Remoting Basic(10)-创建不同宿主的客户端与服务器端
  • .NET 跨平台图形库 SkiaSharp 基础应用
  • .NET 设计模式初探
  • .NET下ASPX编程的几个小问题
  • @ConfigurationProperties注解对数据的自动封装
  • [ vulhub漏洞复现篇 ] Jetty WEB-INF 文件读取复现CVE-2021-34429
  • [ 云计算 | AWS ] 对比分析:Amazon SNS 与 SQS 消息服务的异同与选择
  • [.NET 即时通信SignalR] 认识SignalR (一)
  • []利用定点式具实现:文件读取,完成不同进制之间的
  • [2009][note]构成理想导体超材料的有源THz欺骗表面等离子激元开关——