今天看的是第三章-装饰者模式。
又出现了一个设计原则:类应该对扩展开放,对修改关闭。
装饰者模式:动态地将责任附加到对象上。想要扩展功能,装饰者提供有别于继承的另一种选择。
看书过程中整理的书中的代码如下:
一、装饰者和被装饰者继承的共同的抽象类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;
}
}
}
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;
}
}
}
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();
}
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;
}
}
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;
}
}
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;
}
}
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; } }
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());
}
}