zoukankan      html  css  js  c++  java
  • 设计模式-装饰模式

        本篇文章主要讲解装饰模式。

        装饰模式:动态地给对象添加一些额外的职责,就增加功能来说,装饰模式比生产子类更为灵活。

                  装饰模式(Decorator)结构图

        

        Component是定义一个对象接口,可以给这些对象动态地添加职责。ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。

        来看看基本的代码实现。

        

    package com.lwx.decorator;
    
    /**
     * Created with IntelliJ IDEA.
     * Description:
     * User: lwx
     * Date: 2019-02-27
     * Time: 21:17
     */
    public interface Component {
    
        void operation();
    
    }
    package com.lwx.decorator;
    
    /**
     * Created with IntelliJ IDEA.
     * Description:
     * User: lwx
     * Date: 2019-02-27
     * Time: 21:18
     */
    public class ConcreteComponent implements Component {
    
        public void operation() {
            System.out.println("具体的对象操作");
        }
    
    }
    package com.lwx.decorator;
    
    /**
     * Created with IntelliJ IDEA.
     * Description:
     * User: lwx
     * Date: 2019-02-27
     * Time: 21:19
     */
    public class Decorator implements Component {
    
        protected Component component;
    
        public void setComponent(Component component) {
            this.component = component;
        }
    
        //重写operation方法,实际执行的是Component类中的operation方法
        public void operation() {
            if (component != null) {
                component.operation();
            }
        }
    }
    package com.lwx.decorator;
    
    /**
     * Created with IntelliJ IDEA.
     * Description:
     * User: lwx
     * Date: 2019-02-27
     * Time: 21:21
     */
    public class ConcreteDecoratorA extends Decorator {
    
        @Override
        public void operation() {
            super.operation();
            System.out.println("具体装饰对象A的操作");
        }
    }
    package com.lwx.decorator;
    
    /**
     * Created with IntelliJ IDEA.
     * Description:
     * User: lwx
     * Date: 2019-02-27
     * Time: 21:22
     */
    public class ConcreteDecoratorB extends Decorator {
    
        @Override
        public void operation() {
            super.operation();
            addedBehavior();
            System.out.println("具体装饰对象B的操作");
        }
    
        private void addedBehavior() {
            System.out.println("装饰对象B独有方法");
        }
    
    }

        最后看下测试类和运行结果。

    package com.lwx.decorator;
    
    /**
     * Created with IntelliJ IDEA.
     * Description:
     * User: lwx
     * Date: 2019-02-27
     * Time: 21:24
     */
    public class ComponentTest {
    
        public static void main(String[] args) {
            ConcreteComponent c = new ConcreteComponent();
            ConcreteDecoratorA d1 = new ConcreteDecoratorA();
            ConcreteDecoratorB d2 = new ConcreteDecoratorB();
            d1.setComponent(c);
            d2.setComponent(d1);
            d2.operation();
    
        }
    
    }

        下面是装饰模式在I/O库中的应用(图片来自http://www.zuoxiaolong.com/blog/article.ftl?id=115

        

        现在我们来编写一个装饰者把输入流内所有的数字去掉。  

        先在D盘新建一个记事本,内容随便写,只要加几个数字就行;然后我们开始编写装饰者。

    package com.lwx.decorator.example;
    
    import java.io.FilterInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    /**
     * Created with IntelliJ IDEA.
     * Description:
     * User: lwx
     * Date: 2019-03-03
     * Time: 12:11
     */
    public class RemoveNumberInputStream extends FilterInputStream {
    
        protected RemoveNumberInputStream(InputStream in) {
            super(in);
        }
    
        @Override
        public int read() throws IOException {
            //获取返回的字节,如果是文件末尾返回-1
            int c = super.read();
            if (c != -1) {
                //判断字节是否为数字
                if (Character.isDigit(c)) {
                    // '' 代表空字节
                    char empty = '';
                    return empty;
                }
            }
            return c;
        }
    }

        测试类

    package com.lwx.decorator.example;
    
    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    /**
     * Created with IntelliJ IDEA.
     * Description:
     * User: lwx
     * Date: 2019-03-03
     * Time: 12:33
     */
    public class InputStreamTest {
    
        public static void main(String[] args) {
            try {
                int c;
                InputStream inputStream = new FileInputStream("D:\test.txt");
                RemoveNumberInputStream in = new RemoveNumberInputStream(inputStream);
                while ((c = in.read()) >= 0) {
                    System.out.print((char) c);
                }
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

         我记事本写的内容是:dasdsa1sadsa2dd5sad4sad2dsa9das3,然后运行结果为:

        总结一下装饰模式的优点和缺点:

        优点: 

        1.装饰模式比生成子类更为灵活

        2.把类的核心职责和装饰功能分开,可以去除相关类中重复的装饰逻辑

        缺点:

        1.装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得复杂

        2.这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。

        最后附上demo的githup地址:https://github.com/yijinqincai/design_patterns

  • 相关阅读:
    python之HtmlTestRunner(一)生成测试报告
    测试场景分析-上传文件软件
    测试场景分析-一只钢笔
    md文件的基本常用编写语法
    ipad4密码忘记锁定了如何破解
    python之unittest验证函数功能
    python之排序的几种方法
    python之导入模块的方法
    面经-蘑菇街
    面经-有赞
  • 原文地址:https://www.cnblogs.com/leisurexi/p/10464459.html
Copyright © 2011-2022 走看看