设计模式 -> 装饰者模式

装饰者模式

装饰者模式,指在不改变现有对象结构的情况下,动态的给对象添加一些额外的职责。

  • 装饰者模式用于扩展对象的功能,用于代替继承扩展的方式
  • 装饰者模式就是一种简单的包装逻辑,把你要包装的类传入装饰者类
  • 装饰者类围绕要包装的类做功能的添加

实现 -> 要灵活使用,并不是说一定要一个接口什么的

一个接口,一个实现接口的主类,实现接口的抽象装饰类,具体的装饰类

我们用Java中InputStream举例

在这里插入图片描述

  • 接口 -> InputStream: 是一个抽象类

在这里插入图片描述

  • 被装饰者类 -> 已经完成设计的类

    • FileInputStreamByteArrayInputStream等:相当于装饰者模式的具体组件。实现自InputStream。
      在这里插入图片描述
  • 抽象装饰类 -> FilterInputStream:抽象装饰者类。继承InputStream

    //里面的方法也都是 简单的调用传进来的被装饰者
    protected volatile InputStream in;
    protected FilterInputStream(InputStream in) {
        this.in = in;
    }
    //这里的read()方法不一样会调用到,可能后面包装类直接返回in去被包装类调用了,不一定会结果这个方法
    //所以这个方法实际上只是因为有返回值,需要一个返回值而随便写的,重点是构造方法要传入InputStream
    public int read() throws IOException {
        return in.read();
    }
    public int available() throws IOException {
        return in.available();
    }
    

在这里插入图片描述

  • 具体的装饰类 -> BufferedInputStreamCheckedInputStream等:继承自FilterInputStream

    • BufferedInputStream举例 -> 在包装类中调用read()会执行各种逻辑
      • 但是无论如何最终都会调用被包装类自己本身的那个read()
    //传入被包装类
    public BufferedInputStream(InputStream in, int size) {
        super(in);
    }
    //这个read()中在 fill()方法会调用被包装类自己的read()
    public synchronized int read() throws IOException {
        if (pos >= count) {
            fill();
            if (pos >= count)
                return -1;
        }
        return getBufIfOpen()[pos++] & 0xff;
    }
    //这里调用被包装类自己的方法,这里getInIfOpen()方法直接返回了被包装类,所以read不会经过抽象类
    fill(){
    	int n = getInIfOpen().read(buffer, pos, buffer.length - pos);    
    }
    
    

在这里插入图片描述

  • main方法

    public static void main(String[] args) throws Exception {
        try {
            // 通过缓冲区数据向输入流添加功能,维护一个内部缓冲区以存储从底层输入流读取的字节:
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\text.txt"));
            byte byteData;
            //这里read()方法先调用BufferedInputStream的包装逻辑
            //再中间某个位置调回FileInputStream的read()方法
            while ((byteData = (byte) bis.read()) != -1) {
                System.out.print((char) byteData);
            }
            bis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

装饰者模式和代理模式

  • 装饰者模式就是用于扩展对象的,和代理模式有相似之处

    • 代理模式也可以做到类似装饰者模式这样对一个方法做调整,修改
    • 本质上都是一种委托机制
    • 主类委托代理类完成逻辑
    • 主类委托装饰类完成逻辑
  • 网上有这样的说法 -> 代理和真实对象之间的的关系通常在编译时就已经确定了,而装饰者能够在运行时递归地被构造

  • 我自己觉得装饰者模式其实就是代理模式的一种特殊场景

  • 装饰者模式的初衷就是添加扩展,添加一层装饰,所以不能影响对象核心功能,否则就失去了装饰的意义

  • 而代理模式虽说主张是控制对象的访问,但其实也可以作为扩展使用,AOP就是很好的例子

  • 所以用装饰者模式的地方可以用代理模式替换

  • 而用代理模式的地方,装饰者模式只能替换一部分,否则他就不叫装饰者,你在瞎写

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值