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

      装饰者模式:动态地将责任附加到对象上。想要扩展功能,装饰者提供有别于继承的另一种选择。

       现在,我们有一个场景,咖啡店出售各种不同的咖啡,而不同的咖啡中可以加入各种不同的调料,根据咖啡种类和加入的调料来计算价格。下面我们就用代码来简单实现下这个场景,也就是装饰者模式,其中咖啡为主体,调料是用来装饰咖啡的,比如想要一杯摩卡和奶泡的深焙咖啡,那么要做的是:

      1:拿一个深焙咖啡DarkRoast对象

      2:以摩卡Mocha对象来进行装饰

      3:以奶泡Whip对象进行装饰

      4:调用cost方法,并依赖委托将调料价格加上去。

      好了,直接上代码理解装饰者模式吧。

      第一步:先创建一个基类,所有咖啡和调料都是扩展自这个类的。这就说明装饰者和被装饰者对象都有相同的超类型。

    //基类
    public abstract class Coffer {
        String descirption = "Unknown Coffer";
        
        public String getDescription(){
            return descirption;
        }
        
        //所有子类必须实现这个方法来计算价格
        public abstract double cost();
    }

      第二步:创建一个调料的抽象类,也就是装饰者类,具体的装饰者类实现此类。

    //抽象的装饰者,调料类,扩展自Coffer
    public abstract class Condiment extends Coffer{
        public abstract String getDescription();
    }

      第三步:创建具体的咖啡类。

    //具体的咖啡种类——浓缩咖啡类
    public class Espresso extends Coffer{
        
        public Espresso(){
            descirption = "Espresso";
        }
    
        @Override
        public double cost() {
            return 1.99;
        }
    }
    //具体的咖啡种类——深焙咖啡类
    public class DarkRoast extends Coffer{
            
        public DarkRoast(){
            descirption = "DarkRoast";
        }
    
        @Override
        public double cost() {
            return 0.88;
        }
    }

      第四步:创建具体的调料类

    //具体的装饰者,摩卡调料
    public class Mocha extends Condiment {
        //用于记录被装饰者,这里是在构造方法中将参数记录到咖啡的实例变量中,你也可以使用get/set方法
        Coffer coffer;
        
        public Mocha(Coffer coffer){
            this.coffer = coffer;
        }
        
        @Override
        public String getDescription() {
            return coffer.getDescription() + ", Mocha";
        }
    
        @Override
        public double cost() {
            return 0.2 + coffer.cost();
        }
    }
    //具体的装饰者,奶泡调料
    public class Whip  extends Condiment{
        Coffer coffer;
        
        public Whip(Coffer coffer){
            this.coffer = coffer;
        }
        
        @Override
        public String getDescription() {
            return coffer.getDescription() + ", Whip";
        }
    
        @Override
        public double cost() {
            return 0.15 + coffer.cost();
        }
    }

      第五步:测试

    public class Test {
        public static void main(String[] args) {
            //来一杯Espresso咖啡
            Coffer coffer = new Espresso();
            System.out.println(coffer.getDescription() + ",价格:" + coffer.cost());
            
            //来一杯深焙咖啡,加入2分摩卡和1分奶泡
            Coffer coffer2 = new DarkRoast();
            coffer2 = new Mocha(coffer2);
            coffer2 = new Mocha(coffer2);
            coffer2 = new Whip(coffer2);
            System.out.println(coffer2.getDescription() + ",价格:" + coffer2.cost());
        }
    }

      运行结果:

      

      好了,这就是一个简单的装饰者模式了。在Java的API中,你可以发现,有关IO类就是采用装饰者模式的,如:

          LineNumberInputStream inputStream = new LineNumberInputStream(new BufferedInputStream(new FileInputStream(fileName)));

      顶层类都是InputStream,具体这里不讲解了。

      下一节:工厂模式

    作者:哀&RT
    出处:博客园哀&RT的技术博客--http://www.cnblogs.com/Tony-Anne/
    您的支持是对博主最大的鼓励,感谢您的认真阅读。
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    MongoDB权限管理
    Termux结合公网kali打造移动渗透神器
    整人病毒vbs大全!
    mongodb 数据库详解
    mongodb 用户及数据库管理命令
    windows入侵排查思路
    linux 下node.js 安装
    Linux下如何用/proc命令查找进程状态信息——当前目录,内存占用,描述符等
    linux c 得到指定进程内存占用
    1分钟彻底理解C语言指针
  • 原文地址:https://www.cnblogs.com/Tony-Anne/p/6501323.html
Copyright © 2011-2022 走看看