• 装饰器模式


    参考文章:

    http://blog.csdn.net/hust_is_lcd/article/details/7884320

    http://blog.csdn.net/hguisu/article/details/7531960


    定义:

        是指对一个类的功能进行扩展,同时保证不修改原类的代码。(遵循开闭原则)

    解决的问题:

    • 需要动态地扩展一个类的功能时,非常灵活,可增可消。(注意,继承只能静态地扩展,无法消去)。
    • 装饰模式用于弥补类继承模式无法遵循里氏代换原则的不足。

    模式组成:

    抽象组件角色(Component):定义一个对象接口,以规范准备接受附加责任的对象,

    即可以给这些对象动态地添加职责。

    具体组件角色(ConcreteComponent) :被装饰者,定义一个将要被装饰增加功能的类。

    可以给这个类的对象添加一些职责

    抽象装饰器(Decorator):维持一个指向构件Component对象的实例,

    并定义一个与抽象组件角色Component接口一致的接口

    具体装饰器角色(ConcreteDecorator):向组件添加职责。

    uml类图:



    优点:

    • 动态的扩展一个类的功能,可增加可删除。(继承只能增加功能,无法删除)
    • 可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象
    • 弥补类继承模式无法遵循里氏代换原则的不足。
    • 避免在层次结构高层的类有太多的特征 。Decorator模式提供了一种“即用即付”的方法来添加职责

    应用场景:

    • 需要在不影响其他对象的情况下,以动态、透明的方式给对象添加职责
    • 如果不适合使用子类来进行扩展的时候,可以考虑使用装饰器模式


    Java中的IO是明显的装饰器模式的运用。FilterInputStream,FilterOutputStream,FilterRead,FilterWriter分别为具体装饰器的父类,相当于Decorator类,它们分别实现了InputStream,OutputStream,Reader,Writer类(这些类相当于Component,是其他组件类的父类,也是Decorator类的父类)。继承自InputStream,OutputStream,Reader,Writer这四个类的其他类是具体的组件类,每个都有相应的功能,相当于ConcreteComponent类。而继承自FilterInputStream,FilterOutputStream,FilterRead,FilterWriter这四个类的其他类就是具体的装饰器对象类,即ConcreteDecorator类。通过这些装饰器类,可以给我们提供更加具体的有用的功能。如FileInputStream是InputStream的一个子类,从文件中读取数据流,BufferedInputStream是继承自FilterInputStream的具体的装饰器类,该类提供一个内存的缓冲区类保存输入流中的数据。我们使用如下的代码来使用BufferedInputStream装饰FileInputStream,就可以提供一个内存缓冲区来保存从文件中读取的输入

    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); //其中file为某个具体文件的File或者FileDescription对象   

    装饰器模式vs代理模式


    相同点:实现基本相同

    区别:

    • 代理模式中,代理类对被代理的对象有控制权,决定其执行或者不执行。
    • 装饰模式中,装饰类对代理对象没有控制权,只能为其增加一层装饰,以加强被装饰对象的功能,仅此而已。

    举个栗子:

    定义抽象角色

    abstract class Food {
        public abstract String getDesc();
    }

    定义抽象装饰器

    abstract class FoodDecoration extends Food {
        @Override
        public abstract String getDesc();
    }

    定义具体的角色

    class Duck extends Food {
        @Override
        public String getDesc() {
            return "鸭肉";
        }
    }

    定义具体装饰器

    class RoastFood extends FoodDecoration {
        private Food food;
    
        public RoastFood(Food f) {
            this.food = f;
        }
        @Override
        public String getDesc() {
            return getDecoration() + food.getDesc();
        }
        private String getDecoration() {
            return "烤";
        }
    }

    定义具体装饰器

    class SteamedFood extends FoodDecoration {
    
        private Food food;
    
        public SteamedFood(Food f) {
            this.food = f;
        }
    
        @Override
        public String getDesc() {
            return getDecoration() + food.getDesc();
        }
    
        private String getDecoration() {
            return "蒸";
        }
    }

    客户端调用

    public static void main(String[] args) {
            // 创建食物
            Food food = new Duck();
            // 加入修饰者
            RoastFood rf = new RoastFood(food);
            System.out.println(rf.getDesc());
            // 加入又一个修饰者
            SteamedFood sf = new SteamedFood(rf);
            System.out.println(sf.getDesc());
        }

    输出

  • 相关阅读:
    csp 通信网络
    从客户端(content="xxxxx")中检测到有潜在危险的 Request.Form 值——较合理解决方案
    HttpUtility.HtmlEncode 方法
    web程序防止攻击的一些资料——整理
    memcached——学习
    VS2015 无法启动IIS Express Web服务器
    文件上传——资料收集
    水晶报表-需要安装软件
    web安全漏洞相关
    javascript一个在网页上画线的库
  • 原文地址:https://www.cnblogs.com/amei0/p/7929987.html
Copyright © 2020-2023  润新知