• 三、装饰者模式


    定义:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

    这里写图片描述

    • 个人理解

      1、装饰者存在两个重要的组成部分,需要被装饰的组件(被装饰者)和装饰者抽象。每个装饰者需要持有一个组件,也就是说,装饰者需要持有Component抽象的引用。
      2、装饰者和被装饰者必须是一样的类型也就是要有共同的超类,这是装饰者模式的关键。(因为装饰者必须要能取代被装饰者)
      3、在以上 的类图中,继承Beverage类,是为了有正确的类型,而不是继承它的行为。行为来自于装饰者和基础组件。或者其他装饰者之间的组合关系。(如果依赖继承,那么类的行为只能在编译时静态决定,也就是说,行为不是来自于超类就是子类覆盖后的版本)

    • 要点
      1、继承属于扩展形式之一,但不见得是达到弹性的最佳方案。
      2、在我们的设计中,应该允许行为可以被扩展,而无需修改现有的代码
      3、组合和委托可以在运行时动态地加上新的行为。
      4、除了继承,装饰者模式也可以让我们扩展行为。
      5、装饰者模式以为者一群装饰者类,这些类用来包装具体组件 。
      6、装饰者类反应出被装饰者的组件类型(事实上,他们具有相同的类型,都通过接口或继承实现)。
      7、装饰者可以在被装饰者的行为前面/或后面加上自己的行为,甚至将被装饰者的行为整个取代掉,而达到特定的目的。
      8、你可以用无数个装饰者包装一个组件。
      9、装饰者一般对组件的客户是透明的,除非客户程序依赖于具体的组件。
      10、装饰者会导致设计中出现很多小的对象,如果过度使用,会让程序变得复杂。

    • Java IO 的简单类图UML

    使用装饰者模式,建立一个新的装饰者完成实现将字符串的小写变成大写。

    • LowerCaseInputStream 类,实现将字符的小写变成大写。
    public class LowerCaseInputStream extends FilterInputStream {
    
        public LowerCaseInputStream(InputStream in) {
            super(in);
        }
    
        public int read() throws IOException {
            int c = super.read();
            return (c == -1 ? c : Character.toLowerCase((char)c));
        }
    
        public int read(byte[] b, int offset, int len) throws IOException {
            int result = super.read(b, offset, len);
            for (int i = offset; i < offset+result; i++) {
                b[i] = (byte)Character.toLowerCase((char)b[i]);
            }
            return result;
        }
    }
    
    • 测试类
    public class InputTest {
        public static void main(String[] args) throws IOException {
            int c;
            try {
                InputStream in = new LowerCaseInputStream(new BufferedInputStream(new FileInputStream("test.txt")));
                while ((c = in.read()) >= 0) {
                    System.out.print((char) c);
                }
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    说明:以上代码来自于HeadFirst书籍智慧,请参考原书,获得更多知识。

  • 相关阅读:
    软件测试工程师linux十大场景命令使用
    用yum安装软件显示错误:cannot find a valid baseurl for repo: base
    Redis安装、启动与多端口配置
    Linux vi编辑器
    cookie 和session、三种保持登陆会话的方式
    服务器内存溢出问题
    selenium多窗口切换
    Turtle库的学习积累
    高频ES6
    事件冒泡和捕获的执行顺序
  • 原文地址:https://www.cnblogs.com/huacesun/p/6622492.html
Copyright © 2020-2023  润新知