zoukankan      html  css  js  c++  java
  • 设计模式整理_装饰者模式

      装饰者模式将责任附加在对象上,若要扩展功能,装饰者提供了比继承更加有弹性的替代方案.

      采用装饰者模式的时候,需要注意以下几点:

    1. 装饰者和被装饰者对象,有相同的超类型.(继承是为了有正确的类型,而不是继承行为,行为来自于被装饰者和基础的组件).
    2. 可以用一个或多个装饰者包装一个对象.
    3. 装饰者可以在所委托被装饰者的行为前或者行为后,增加自己的行为.
    4. 如果代码是依赖于具体的组件类型而不是针对抽象组件类型编程的时候,就会导致程序出现问题.因此应该具体类型具体分析.
    5. 装饰者模式体现了对于扩展开放和对于修改关闭的原则.

      在Java中,装饰者模式最直接的体现就是IO包里的,例如,LineNumberInputStream ll=new LineNumberInputStream(new BufferedInputStream(new FlieInputStream()));

      下面是装饰者模式的体现:代码采用了Beverage类作为公共的超类,CondimentDecorator作为需要装饰者类,可以看出装饰者模式是针对抽象父类进行编程的,因此装饰者模式在碰到需要具体子件发挥作用的时候,会碰壁.

    public abstract class Beverage /*饮料类是一个抽象类,是被装饰的对象.*/{
        String description="Unknown Beverage";
        
        public String getDescription() {
            return description;
        }
        
        public abstract double cost();
    }
    class Espresso extends Beverage /*具体的实现类*/{
        
        public Espresso() {
            description="Espresso";
        }
    
        @Override
        public double cost() {
            return 1.99;
        }
        
    }
    public abstract class CondimentDecorator/*装饰者*/ extends Beverage{
        public abstract String getDescription();
    }
    class Mocha extends CondimentDecorator {
        Beverage beverage;
        
        public Mocha(Beverage beverage)/*针对抽象组件编程*/ {
            super();
            this.beverage = beverage;
        }
    
        @Override
        public String getDescription() {
            return beverage.getDescription()+",Mocha";
        }
    
        @Override
        public double cost() {
            return 0.20+beverage.cost();
        }
        
    }
    /*
     * 测试装饰模式
     * */
    public class Test {
        public static void main(String[] args) {
            Beverage bev=new Espresso();    //建立被装饰的对象
            
            System.out.println(bev.getDescription()+" $"+bev.cost());
            bev=new Mocha(bev);        //用Mocha装饰
            bev=new Mocha(bev);        //由于上一步的Mocha继承了Beverage类,因此可以这么装饰.
            System.out.println(bev.getDescription()+" $"+bev.cost());
        }
    }

      下面是具体的类图:

  • 相关阅读:
    TLS回调函数
    MySQL-based databases CVE-2016-6664 本地提权
    go语文中panic的使用
    Redis实现分布式锁与任务队列的思路
    mysql添加权限权限用户
    php压缩html代码减少页面响应时间
    Docker搭建nginx+php-fpm运行环境
    vscode使用phpxdebug调试
    PHP7引用类型
    PHPFPM模式三种运行模式
  • 原文地址:https://www.cnblogs.com/hlhdidi/p/5596795.html
Copyright © 2011-2022 走看看