设计形式之Decorator(装饰者模式)

设计模式之Decorator(装饰者模式)
装饰者模式:装饰顾名思义就在原来的功能基础上加点装饰。
在java api中用到装饰者模式的最典型的就是IO流那部分了。
之前我的一篇文章中也用到装饰者模式:
http://skyuck.iteye.com/blog/781065
设计形式之Decorator(装饰者模式)



下面还是来用一个场景来描述吧:
很经典的一个场景就是咖啡的例子。例如我们喝咖啡一般有蓝山咖啡,拿铁咖啡等等。但是有时候我们去喝咖啡时需要加糖啊,咖啡也分为大杯,中杯,小杯。这样不同的咖啡价格就会不一样。
那么我们怎么去描述这些呢?

首先当然是我们的咖啡接口了
package com.unis.decorator;

public interface Coffee {
	
	double getPrice();
	
	String getInformation();

}

然后当然是对应到具体的咖啡
package com.unis.decorator;

public class LatteCoffee implements Coffee {

	@Override
	public String getInformation() {
		return "拿铁咖啡";
	}

	@Override
	public double getPrice() {
		return 15;
	}

}

package com.unis.decorator;

public class BlueMountainCoffee implements Coffee {

	@Override
	public String getInformation() {
		return "蓝山咖啡";
	}

	@Override
	public double getPrice() {
		return 30;
	}

}


为了让coffee可以被修饰,当然这里最重要的一个类就是我们的装饰者
package com.unis.decorator;

public class Decorator implements Coffee {
	
	private Coffee coffee;
	
	public Decorator(Coffee coffee) {
		this.coffee = coffee;
	}

	@Override
	public String getInformation() {
		return coffee.getInformation();
	}

	@Override
	public double getPrice() {
		return coffee.getPrice();
	}

}


有了装饰者我们就可以为咖啡来随意的添加一些附属的东西。
package com.unis.decorator;

public class SugarCoffee extends Decorator {

	public SugarCoffee(Coffee coffee) {
		super(coffee);
	}

	@Override
	public String getInformation() {
		return "加糖的"+super.getInformation();
	}

	@Override
	public double getPrice() {
		return super.getPrice()*1.5;
	}
	
	

}

package com.unis.decorator;

public class LargeCoffee extends Decorator{

	public LargeCoffee(Coffee coffee) {
		super(coffee);
	}

	@Override
	public String getInformation() {
		return "大杯的"+super.getInformation();
	}

	@Override
	public double getPrice() {
		return super.getPrice()+2;
	}
	
	

}




最后就是我们的测试类了:
package com.unis.decorator;

public class Test {

	public static void main(String[] args) {
	 	Coffee c = new LargeCoffee(new BlueMountainCoffee());
	 	System.out.println(c.getInformation());
	 	System.out.println(c.getPrice());
	}
}



观察Decorator类。这个类要实现Coffee接口。并且在这个类中要包含Coffee这个接口。
1 楼 zhaoxy_sunrain 2011-03-31  
按照博主的写法写了下,发现一个好玩的问题。
我写了一个这样的测试类:
              Coffee coffee = new  SugarCoffee(new LargeCoffee(new LatteCoffee()));
int  price = coffee.getPrice();
System.out.println(price);


这是一个加糖的大杯的拿铁咖啡;

那么再来一个,大杯的加糖的拿铁咖啡
Coffee coffee = new  LargeCoffee(new SugarCoffee(new LatteCoffee()));

结果打印出来的价钱就不一样了,按照程序逻辑很好理解,但是怎么处理这种情况呢
2 楼 kfc_davy 2011-04-27  
zhaoxy_sunrain 写道
按照博主的写法写了下,发现一个好玩的问题。
我写了一个这样的测试类:
              Coffee coffee = new  SugarCoffee(new LargeCoffee(new LatteCoffee()));
int  price = coffee.getPrice();
System.out.println(price);


这是一个加糖的大杯的拿铁咖啡;

那么再来一个,大杯的加糖的拿铁咖啡
Coffee coffee = new  LargeCoffee(new SugarCoffee(new LatteCoffee()));

结果打印出来的价钱就不一样了,按照程序逻辑很好理解,但是怎么处理这种情况呢

一个是×一个是+。。