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