前言
本文来自《Head Fist 设计模式》一书的实例,这里仅仅是个人笔记记录
需求
我需要一杯咖啡,但是需要加牛奶和白糖,请算出价格
我们可以拆解为咖啡,装饰着牛奶和白糖,例如像下面这样套着
/**
* 咖啡+牛奶+白糖
*
* 所谓装饰描述: 即原味咖啡的基础上,装饰: 牛奶 MilkCondiment,再装饰:白糖 SugarCondiment
*/
private void updateUI() {
BaseBaverage mCoffee = new Coffee();
BaseBaverage mMilkCoffee = new MilkCondiment(mCoffee);
BaseBaverage mSugarMilkCoffee = new SugarCondiment(mMilkCoffee);
String result = mSugarMilkCoffee.getDiscribtion() + " cost = " + mSugarMilkCoffee.cost();
tv_info.setText(result);
Log.d(Contants.TAG, result);
//运行结果 Coffee + MilkCondiment + SugarCondiment cost = 22
}
上述不管是咖啡,还是配料牛奶、白糖都是继承同一个基类或超类,来着这样就可以上述进行相互组合了。
装饰者基类
package com.su.decoratormode.domain;
public abstract class BaseBaverage {
// 便于知悉子类谁谁谁
public abstract String getDiscribtion();
// 价格咯
public abstract int cost();
}
主料咖啡类
package com.su.decoratormode.domain;
public class Coffee extends BaseBaverage {
private static final int mCost = 15;
@Override
public String getDiscribtion() {
return Coffee.class.getSimpleName();
}
@Override
public int cost() {
return mCost;
}
}
配料-牛奶
package com.su.decoratormode.domain;
public class MilkCondiment extends BaseBaverage {
private int mCost = 5;
private BaseBaverage mBaseBaverage;
public MilkCondiment(BaseBaverage mBaseBaverage) {
this.mBaseBaverage = mBaseBaverage;
}
@Override
public String getDiscribtion() {
return mBaseBaverage.getDiscribtion() + " + " + MilkCondiment.class.getSimpleName();
}
@Override
public int cost() {
return mCost + mBaseBaverage.cost();
}
}
配料-白糖
package com.su.decoratormode.domain;
public class SugarCondiment extends BaseBaverage {
private int mCost = 2;
private BaseBaverage mBaseBaverage;
public SugarCondiment(BaseBaverage mBaseBaverage) {
this.mBaseBaverage = mBaseBaverage;
}
@Override
public String getDiscribtion() {
return mBaseBaverage.getDiscribtion() + " + " + SugarCondiment.class.getSimpleName();
}
@Override
public int cost() {
return mCost + mBaseBaverage.cost();
}
}
结语
没想到吧,装饰者模式就这么短。但是在 JAVA API中装饰者模式大量被运用到哦。
举个栗子
FileInputStream fis;
BufferedInputStream bis;
LineNumberInputStream lis;