[设计模式] 装饰者模式 decorate (Head First 设计模式)

源码和图片来自 head first 设计模式

一. 开闭原则

类应该对扩展开放, 对修改关闭;

二. 装饰者模式描述

装饰者模式, 动态地将责任附加到对象上.若要扩展功能, 装饰者提供了比继承更有弹性的替代方案[设计模式] 装饰者模式 decorate (Head First 设计模式)
[设计模式] 装饰者模式 decorate (Head First 设计模式)
[设计模式] 装饰者模式 decorate (Head First 设计模式)

完整代码下载

二. 代码

高层抽象 Beverage

public abstract class Beverage {

	String description = "Unknown Beverage";
	
	public String getDescription() {
		return description;
	}
	
	public abstract double cost();
}
public class Espresso extends Beverage {

	public Espresso() {
		description = "Espresso";
	}
	
	@Override
	public double cost() {
		return 1.99;
	}

}

装饰器 CondimentDecorator

public abstract class CondimentDecorator extends Beverage {

	public abstract String getDescription();

}
public class Milk extends CondimentDecorator {

	Beverage beverage;
	
	public Milk(Beverage beverage) {
		super();
		this.beverage = beverage;
	}

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

	@Override
	public double cost() {
		return .33 + beverage.cost();
	}

}

四. 测试代码

public class StarbuzzCoffee {

	public static void main(String[] args) {
		Beverage beverage = new Espresso();
		System.out.println(beverage.getDescription() + " $" + beverage.cost());
		
		Beverage beverage2 = new DarkRoast();
		
		beverage2 = new Mocha(beverage2);
		beverage2 = new Mocha(beverage2);
		beverage2 = new Whip(beverage2);
		System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
		
		Beverage beverage3 = new HouseBlend();
		beverage3 = new Mocha(beverage3);
		beverage3 = new Soy(beverage3);
		beverage3 = new Whip(beverage3);
		System.out.println(beverage3.getDescription() + " $" + beverage3.cost());
	}

}

输出:

Espresso $1.99
Dark Roast Coffee, Mocha, Mocha ,Whip $1.06
House Blend Coffee, Mocha ,Soy ,Whip $2.08

五. 装饰 java.io

[设计模式] 装饰者模式 decorate (Head First 设计模式)
实现转小写的出入流

public class LowerCaseInputStream extends FilterInputStream {

	public LowerCaseInputStream(InputStream inputStream) {
		super(inputStream);
	}

	@Override
	public int read() throws IOException {
		int c = super.read();
		return (c == -1 ? c : Character.toLowerCase((char)c));
	}

}

测试代码

	public static void toLower() {
		int c;
		try {
			InputStream in = new LowerCaseInputStream(
					new BufferedInputStream(
							new FileInputStream("count.txt")));
			StringBuilder sb = new StringBuilder();
			while((c = in.read()) != -1) {
				sb.append((char)c);
			}
			System.out.println(sb.toString());
			in.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

输出:

APP.CHEN.COM

1
app.chen.com

1