zoukankan      html  css  js  c++  java
  • 尚硅谷设计模式笔记-装饰者模式


    笔记来源:尚硅谷

    一、需求

    星巴克咖啡订单项目(咖啡馆) :

    1. 咖啡种类/单品咖啡: Espresso(意大利浓咖啡)、 ShortBlack、 LongBlack(美式
      咖啡)、Decaf(无因咖啡)
    2. 调料: Milk、 Soy(豆浆)、 Chocolate
    3. 要求在扩展新的咖啡种类时,具有良好的扩展性、改动方便、维护方便
    4. 使用面向对象的方法来计算不同种类咖啡的费用:客户可以点单品咖啡,也可以单品咖
      啡+调料组合。

    二、装饰者方法

    说明

    1. Drink类就是抽象类
    2. LongBlack是单品咖啡
    3. Decorator是一一个装饰类,含有一个被装饰的对象(Drink obj)
    4. Decorator的cost方法进行一个费用的叠加计算,递归的计算价格

    Drink类:

    public abstract class Drink {
    	private String des;//描述
    	private float price = 0.0f;
    	
    	//计算费用的抽象方法
    	//子类实现
    	public abstract float cost();
    	
    	public float getPrice() {
    		return price;
    	}
    	public void setPrice(float price) {
    		this.price = price;
    	}
    	public String getDes() {
    		return des;
    	}
    	public void setDes(String des) {
    		this.des = des;
    	}
    }
    

    创建LongBlack(美式咖啡)类来继承Drink:

    public class LongBlack extends Drink{
    
    	public LongBlack() {
    		setDes("LongBlack");
    		this.setPrice(10.0f);
    	}
    	
    	@Override
    	public float cost() {
    		return getPrice();
    	}
    }
    

    创建装饰者:

    public class Decorator extends Drink {
    
    	private Drink obj;
    	//组合Drink
    	public Decorator(Drink obj) {
    		this.obj = obj;
    	}
    	
    	@Override
    	public float cost() {
    		//getPrice()自己的价格
            //递归计算cost
    		return super.getPrice() + obj.cost();
    	}
    
    	@Override
    	public String getDes() {
    		return des + " " + super.getPrice() + " " + obj.getDes();
    	}
    }
    

    创建装饰者特例Milk:

    public class Milk extends Decorator {
    
    	public Milk(Drink obj) {
    		super(obj);
    		setDes("牛奶");
    		setPrice(3.0f);
    	}
    }
    

    Client调用示例如下:

    public class Client {
    	public static void main(String[] args) {
    		//点一杯美式咖啡
    		Drink drink = new LongBlack();
    		//点牛奶调料
    		drink = new Milk(drink);
    		//点牛奶调料
    		drink = new Milk(drink);
    		//计算价格
    		System.out.println(drink.cost());
    	}
    }
    

    输出如下:


    三、装饰者模式的JDK应用

    在 JDK 的 I/O中,我们列举出部分关系(FilterInpuStream相当于Decorator):

    // FilterInpuStream相当于Decorator,充当了装饰者
    //  (version 1.8 : 52.0, super bit)
    public class java.io.FilterInputStream extends java.io.InputStream {
      
      // Field descriptor #25 Ljava/io/InputStream;
      protected volatile java.io.InputStream in;    //--组合了InputStream
      
      // Method descriptor #26 (Ljava/io/InputStream;)V
      // Stack: 2, Locals: 2
      protected FilterInputStream(java.io.InputStream arg0);
    	
      /*省略*/
    }
    
  • 相关阅读:
    c++ 对象作为参数传递
    LeetCode总结 -- 树的性质篇
    【Bug笔记】The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
    poj3642 Charm Bracelet(0-1背包)
    [笔试题] 阿里巴巴2013技术类笔试题(完整版手工记录+具体解析)
    swift-switch使用方法
    Android OpenGL ES 应用(二) 纹理
    【VBA研究】查找目录以下全部文件的名称
    解决com.ibatis.sqlmap.client.SqlMapException: There is no statement named in this SqlMap
    Android菜鸟的成长笔记(27)——ViewPager的使用
  • 原文地址:https://www.cnblogs.com/theory/p/13338729.html
Copyright © 2011-2022 走看看