HeadFirst设计模式之装饰者模式

今天看的是第三章-装饰者模式。

又出现了一个设计原则:类应该对扩展开放,对修改关闭。

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

看书过程中整理的书中的代码如下:

一、装饰者和被装饰者继承的共同的抽象类Beverage.java

package com.sq.decoratorPattern;

/**
 * 装饰者和被装饰者需要实现的共同的抽象类
 * @author SQ
 *
 */
public abstract class Beverage {
	protected String description = "Unknown Beverage"; //记录咖啡种类
	
	public final static int TALL = 0; //小杯
	public final static int GRANDE = 1; //中杯
	public final static int VENTI = 2; //大杯
	
	protected int size = TALL; //咖啡的大小(大/中/小杯)
	
	/**
	 * 返回咖啡的种类和杯子大小
	 * @return
	 */
	public String getDescription(){
		switch (size) {
	    case Beverage.VENTI:
			return "venti " + description;
		case Beverage.GRANDE:
			return "grande " + description;
		case Beverage.TALL:
			return "tall " + description;
		default:
			return description;
		}
	}
	
	public int getSize() {
		return size;
	}

	public void setSize(int size) {
		this.size = size;
	}

	/**
	 * 返回价格
	 * @return
	 */
	public abstract float cost();
}


二、被装饰者,即咖啡的种类

1、深焙咖啡DarkRoast.java

package com.sq.decoratorPattern.beDecorator;

import com.sq.decoratorPattern.Beverage;

/**
 * 被装饰者类 深焙咖啡
 * @author SQ
 *
 */
public class DarkRoast extends Beverage {
	
	public DarkRoast(int cupSize) {
		description = "Dark Roast Coffee";
		size = cupSize;
	}
	
	@Override
	public int getSize() {
		return size;
	}
	
	@Override
	public float cost() {
		switch (size) {
	    case Beverage.VENTI:
			return 0.99f;
		case Beverage.GRANDE:
			return 0.89f;
		case Beverage.TALL:
			return 0.79f;
		default:
			return 0.0f;
		}
	}

}


2、低咖啡因咖啡Decaf.java

package com.sq.decoratorPattern.beDecorator;

import com.sq.decoratorPattern.Beverage;

/**
 * 被装饰者类 低咖啡因咖啡
 * @author SQ
 *
 */
public class Decaf extends Beverage {
	
	public Decaf(int cupSize) {
		description = "Decaf Coffee";
		size = cupSize;
	}
	
	@Override
	public int getSize() {
		return size;
	}
	
	@Override
	public float cost() {
		switch (size) {
	    case Beverage.VENTI:
			return 1.05f;
		case Beverage.GRANDE:
			return 0.95f;
		case Beverage.TALL:
			return 0.85f;
		default:
			return 0.0f;
		}
	}

}

3、浓缩咖啡Espresso.java

package com.sq.decoratorPattern.beDecorator;

import com.sq.decoratorPattern.Beverage;

/**
 * 被装饰者类 浓缩咖啡
 * @author SQ
 *
 */
public class Espresso extends Beverage {

	public Espresso(int cupSize) {
		description = "Espresso Coffee";
		size = cupSize;
	}
	
	@Override
	public int getSize() {
		return size;
	}
	
	@Override
	public float cost() {
		switch (size) {
	    case Beverage.VENTI:
			return 1.99f;
		case Beverage.GRANDE:
			return 1.89f;
		case Beverage.TALL:
			return 1.79f;
		default:
			return 0.0f;
		}
	}

}

4、综合咖啡HouseBlend.java

package com.sq.decoratorPattern.beDecorator;

import com.sq.decoratorPattern.Beverage;

/**
 * 被装饰者类 综合咖啡
 * @author SQ
 *
 */
public class HouseBlend extends Beverage {

	public HouseBlend(int cupSize) {
		description = "House Blend Coffee";
		size = cupSize;
	}
	
	@Override
	public int getSize() {
		return size;
	}

	@Override
	public float cost() {
		switch (size) {
	    case Beverage.VENTI:
			return 0.89f;
		case Beverage.GRANDE:
			return 0.79f;
		case Beverage.TALL:
			return 0.69f;
		default:
			return 0.0f;
		}
	}

}

三、装饰者,即咖啡中加的配料:

1、装饰者共同实现的抽象类CondimentDecorator.java

package com.sq.decoratorPattern.decorator;

import com.sq.decoratorPattern.Beverage;

/**
 * 装饰者共同实现的抽象类
 * @author SQ
 *
 */
public abstract class CondimentDecorator extends Beverage {
	/**
	 * 装饰者需要实现的返回描述方法
	 */
	public abstract String getDescription();
}

2、牛奶Milk.java

package com.sq.decoratorPattern.decorator;

import com.sq.decoratorPattern.Beverage;

/**
 * 装饰者类 牛奶
 * @author SQ
 *
 */
public class Milk extends CondimentDecorator {
	Beverage beverage;
	
	public Milk(Beverage beverage) {
		this.beverage = beverage;
	}

	@Override
	public int getSize() {
		return beverage.getSize();
	}
	
	@Override
	public String getDescription() {
		return beverage.getDescription() + ", Milk";
	}

	@Override
	public float cost() {
		float cost = beverage.cost();
//    	System.out.println("Milk:" + beverage.cost());
		switch (getSize()) {
	    case Beverage.VENTI:
			cost += 0.20f;
			break;
		case Beverage.GRANDE:
			cost += 0.15f;
			break;
		case Beverage.TALL:
			cost += 0.10f;
			break;
		default:
		}
		return cost;
	}

}

3、摩卡Mocha.java

package com.sq.decoratorPattern.decorator;

import com.sq.decoratorPattern.Beverage;

/**
 * 装饰者类 摩卡
 * @author SQ
 *
 */
public class Mocha extends CondimentDecorator {
	Beverage beverage;
	
	public Mocha(Beverage beverage) {
		this.beverage = beverage;
	}
	
	@Override 
	public int getSize() {
		return beverage.getSize();
	}
	
	@Override
	public String getDescription() {
		return beverage.getDescription() + ", Mocha";
	}

	@Override
	public float cost() {
		float cost = beverage.cost();
    	//System.out.println("Mocha:" + beverage.cost());
		switch (getSize()) {
	    case Beverage.VENTI:
			cost += 0.30f;
			break;
		case Beverage.GRANDE:
			cost += 0.25f;
			break;
		case Beverage.TALL:
			cost += 0.20f;
			break;
		default:
		}
		return cost;
	}

}

4、豆浆Soy.java

package com.sq.decoratorPattern.decorator;

import com.sq.decoratorPattern.Beverage;

/**
 * 装饰者类 豆浆
 * @author SQ
 *
 */
public class Soy extends CondimentDecorator {
	Beverage beverage;
	
	public Soy(Beverage beverage) {
		this.beverage = beverage;
	}

	@Override
	public int getSize() {
		return beverage.getSize();
	}
	
	@Override
	public String getDescription() {
		return beverage.getDescription() + ", Soy";
	}

	@Override
	public float cost() {
		float cost = beverage.cost();
//    	System.out.println("Soy:" + beverage.cost());
		switch (getSize()) {
	    case Beverage.VENTI:
			cost += 0.25f;
			break;
		case Beverage.GRANDE:
			cost += 0.20f;
			break;
		case Beverage.TALL:
			cost += 0.15f;
			break;
		default:
		}
		return cost;
	}

}

5、奶泡Whip.java

package com.sq.decoratorPattern.decorator;

import com.sq.decoratorPattern.Beverage;

/**
 * 装饰者类 奶泡
 * @author SQ
 *
 */
public class Whip extends CondimentDecorator {
	Beverage beverage;
	
	public Whip(Beverage beverage) {
		this.beverage = beverage;
	}
	
	@Override
	public int getSize() {
		return beverage.getSize();
	}

	@Override
	public String getDescription() {
		return beverage.getDescription() + ", Whip";
	}

	@Override
	public float cost() {
		float cost = beverage.cost();
//    	System.out.println("Whip:" + beverage.cost());
		switch (getSize()) {
	    case Beverage.VENTI:
			cost += 0.20f;
			break;
		case Beverage.GRANDE:
			cost += 0.15f;
			break;
		case Beverage.TALL:
			cost += 0.10f;
			break;
		default:
		}
		return cost;
	}

}

四、测试类,星巴兹咖啡厅StarbuzzCoffee.java

package com.sq.decoratorPattern;

import com.sq.decoratorPattern.beDecorator.DarkRoast;
import com.sq.decoratorPattern.beDecorator.Espresso;
import com.sq.decoratorPattern.beDecorator.HouseBlend;
import com.sq.decoratorPattern.decorator.Mocha;
import com.sq.decoratorPattern.decorator.Soy;
import com.sq.decoratorPattern.decorator.Whip;

/**
 * 测试类 星巴兹咖啡
 * 装饰者模式:动态的将责任附加到对象上。想要扩展功能,装饰者提供有别于继承的另一种选择。
 * @author SQ
 *
 */
public class StarbuzzCoffee {
	public static void main(String[] args) {
		Beverage beveEspre = new Espresso(Beverage.TALL); //定一杯小杯Espresso,不需要调料
		System.out.println(beveEspre.getDescription() + ": $" + beveEspre.cost()); //打印Espresso的描述和价钱
		
		Beverage beveDarkRoast = new DarkRoast(Beverage.GRANDE); //定一杯中杯DarkRoast
		beveDarkRoast = new Mocha(beveDarkRoast); //加摩卡,即用Mocha装饰它
		beveDarkRoast = new Mocha(beveDarkRoast); //加第二份摩卡,即再用Mocha装饰它
		beveDarkRoast = new Whip(beveDarkRoast); //加奶泡,即再用Whip装饰它
		System.out.println(beveDarkRoast.getDescription() + ": $" + beveDarkRoast.cost()); //打印加了双份摩卡和一份奶泡的DarkRoast咖啡的描述和价钱
		
		Beverage beveHouseBlend = new HouseBlend(Beverage.VENTI); //定一杯大杯HouseBlend
		beveHouseBlend = new Soy(beveHouseBlend); //加豆浆,即用Soy装饰它
		beveHouseBlend = new Mocha(beveHouseBlend); //加摩卡,即再用Mocha装饰它
		beveHouseBlend = new Whip(beveHouseBlend); //加奶泡,即再用Whip装饰它
		System.out.println(beveHouseBlend.getDescription() + ": $" + beveHouseBlend.cost());
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值