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());
        }
    }

      下面是具体的类图:

  • 相关阅读:
    pygame 笔记-7 生命值/血条处理
    pygame 笔记-6 碰撞检测
    pygame 笔记-5 模块化&加入敌人
    pygame 笔记-4 代码封装&发射子弹
    tk.mybatis通用插件updateByPrimaryKeySelective无法自动更新ON UPDATE CURRENT_TIMESTAMP列的解决办法
    pygame 笔记-3 角色动画及背景的使用
    pygame 笔记-2 模仿超级玛丽的弹跳
    pygame 笔记-1 按键控制方块移动
    mysql技巧:如果记录存在则更新/如果不存在则插入的三种处理方法
    mac上mysql8.0以tar.gz方式手动安装
  • 原文地址:https://www.cnblogs.com/hlhdidi/p/5596795.html
Copyright © 2011-2022 走看看