zoukankan      html  css  js  c++  java
  • 设计模式 之 装饰者(Decorator)模式

    装饰者模式(Decorator):动态地为一个对象添加一些额外的职责,若要扩展一个对象的功能,装饰者提供了比继承更有弹性的替代方案。

    结构图:

    • 抽象构件类(Component):给出一个抽象的接口,用以规范准备接收附加责任的对象
    • 具体构件类(ConcreteComponent):定义一个具体的准备接受附加责任的类,其必须实现Component接口。
    • 装饰者类(Decorator):持有一个构件(Conponent)对象的实例,并定义一个和抽象构件一致的接口。
    • 具体装饰者类(Concrete Decoratator):定义给构件对象“贴上”附加责任。

    下面用一个实例来讲解一下装饰者模式《head first 设计模式》中的例子:比如在星巴兹咖啡馆,人们需要根据自己的爱好来订购咖啡,而具体的coffee种类假设一共用两类:HouseBlend(混合咖啡)和darkRoast(深焙咖啡)。而另外客人也可根据的口味来添加一些其他的东西,例如:摩卡(mocha)、Milk(牛奶)。

    从实例中可以分析出:抽象构件类对应的就是coffee饮品(下面的beverage类),具体构件类对应的就是HouseBlend和darkRoast;具体装饰者类对应mocha和milk口味;至于装饰者类这里没有对应,主要用于具体装饰者类的继承。下面看具体d

    源代码:

    抽象构件类(Component):

    Beverage.java:

    /**
     * @author haifei
     *    抽象构件类
     */
    public abstract class Beverage {
        
        String description = "未知的咖啡";
        
        public String getDescription(){
            return description;
        }
        
        public abstract double cost();
    }

    具体构件类(ConcreteComponent):

    DarkRoast.java:

    /**
     * @author haifei
     *    具体构件类
     */
    public class DarkRoast extends Beverage{
    
        public DarkRoast(){
            description = "深焙咖啡";
        }
        
        @Override
        public double cost() {
            return 1.0;
        }
    
    }

    HouseBlend.java:

    /**
     * @author haifei
     *    具体构件类。HouseBlend代表咖啡中的一种:混合咖啡
     */
    public class HouseBlend extends Beverage{
    
        
        
        public HouseBlend() {
            description = "混合咖啡";
        }
    
        @Override
        public double cost() {
            return .89;
        }
    
    }

    装饰者类(Descorator):

    ConimentDecorator.java:

    /**
     * @author haifei
     *    抽象装饰者类,所有的具体装饰者都必须继承这个类
     */
    public abstract class CondimentDecorator extends Beverage{
    
        public abstract String getDescription();
        
    }

    具体装饰者类(ConcreteDescorator):

    Mocha.java:

    public class Mocha extends CondimentDecorator{
    
        Beverage beverage;
        
        public Mocha(Beverage beverage){
            this.beverage = beverage;
        }
        
        @Override
        public String getDescription() {
            return beverage.getDescription() + ",摩卡";
        }
    
        @Override
        public double cost() {
            return beverage.cost() + .20;
        }
    
    }

    Milk.java:

    public class Milk extends CondimentDecorator{
    
        Beverage beverage;
        
        public Milk(Beverage beverage) {
            this.beverage = beverage;
        }
    
        @Override
        public String getDescription() {
            return beverage.getDescription() + " ,牛奶";
        }
    
        @Override
        public double cost() {
            return beverage.cost() + .10;
        }
    
    }

    客户端(Client):

    StarBuzzCoffee.java:

    public class StarBuzzCoffee {
        public static void main(String[] args){
            
            Beverage beverage1 = new DarkRoast();
            beverage1 = new Milk(beverage1);
            beverage1 = new Mocha(beverage1);
            System.out.println(beverage1.getDescription() + "$" + beverage1.cost());
            
            Beverage beverage2 = new HouseBlend();
            beverage2 = new Milk(beverage2);
            beverage2 = new Mocha(beverage2);
            System.out.println(beverage2.getDescription() + "$" + beverage2.cost());
        }
    }

    运行结果:

    深焙咖啡 ,牛奶,摩卡$1.3
    混合咖啡 ,牛奶,摩卡$1.19
    
  • 相关阅读:
    Vue总结
    Android适配总结
    Java为什么需要四种引用?
    回溯递归:八皇后
    eclipse中的maven build 、maven clean 、 maven install作用
    JS时间格式CST转GMT
    什么是ECMAScript、什么又是ECMA?
    maven打包工程出现错误 Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
    Vue三步完成跨域请求
    Eclipse导入别人项目爆红叉
  • 原文地址:https://www.cnblogs.com/mercuryli/p/5284248.html
Copyright © 2011-2022 走看看