设计模式学习(三)之装饰者模式

设计原则:类应该对扩展开放,对修改关闭
我们的目标是允许类容易扩展,在不修改代码的情况下,就可以搭配新的行为,如能实现这样的目标,这样的设计具有弹性,可以应对改变,可以接受新的功能来应对改变的需求
装饰者和被装饰者对象有相同的超类型
可以用一个或者多个装饰者包装一个对象
既然装饰者和被装饰者有相同的超类型,所以在任何需要原始对象的场合,可以用装饰过的对象代替它
装饰者模式:动态的将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案
装饰者类图

看个具体问题:
有一个咖啡店,他们有几种饮料,比如HouseBlend, DarkRoast.Decaf,Espresso
每种饮料里面可以加调料,可以加一种或者几种,也可以不加,调料有,SteamedMilk.Soy,Mocha等
计算一杯饮料的价格,包括饮料的价格和调料的价格
看一下类图

那么问题来了
如果需要添加新的调料,需要加上新的方法
如果价格修改了,需要修改父类的代码
有些饮料并不适合某些调料,仍然加入了判断
如果需要加入双倍的某种调料呢?

看新的类图

用代码来实现 
package com.alvin.decorator;

public abstract class Beverage {
	protected String description;
	public abstract String getDescription();
	public abstract float cost();

}
package com.alvin.decorator;


public class HouseBlend extends Beverage{
	public float cost(){
		return 1;
	}

	@Override
	public String getDescription() {
		return "HouseBlend";
	}

}
package com.alvin.decorator;

public class Decaf extends Beverage {

	@Override
	public String getDescription() {
		return "Decaf";
	}

	@Override
	public float cost() {
		return 3;
	}

}
package com.alvin.decorator;

public class DarkRoast extends Beverage {

	@Override
	public String getDescription() {
		return "DarkRoast";
	}

	@Override
	public float cost() {
		return 2;
	}

}
package com.alvin.decorator.impl;

import com.alvin.decorator.Beverage;

public abstract class CondimentDecorator extends Beverage {
	

}
package com.alvin.decorator.impl;

import com.alvin.decorator.Beverage;

public class Milk extends CondimentDecorator {
	private Beverage beverage;
	public Milk(Beverage beverage) {
		this.beverage = beverage;
	}

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

	@Override
	public float cost() {
		return beverage.cost() + 0.2f;
	}

}
package com.alvin.decorator.impl;

import com.alvin.decorator.Beverage;

public class Mocha extends CondimentDecorator {
	private Beverage beverage;
	public Mocha(Beverage beverage) {
		this.beverage = beverage;
	}

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

	@Override
	public float cost() {
		return beverage.cost() + 0.1f;
	}

}
package com.alvin.decorator.impl;

import com.alvin.decorator.Beverage;

public class Soy extends CondimentDecorator {
	private Beverage beverage;
	public Soy(Beverage beverage) {
		this.beverage = beverage;
	}

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

	@Override
	public float cost() {
		return beverage.cost() + 0.3F;
	}

}
package com.alvin.decorator;

import com.alvin.decorator.impl.Milk;
import com.alvin.decorator.impl.Mocha;
import com.alvin.decorator.impl.Soy;

public class Run {
	public static void main(String[] args) {
		Beverage beverage = new DarkRoast();
		System.out.println(beverage.getDescription() + beverage.cost());
		
		Beverage beverage1 = new HouseBlend();
		beverage1 = new Mocha(beverage1);
		beverage1 = new Milk(beverage1);
		beverage1 = new Soy(beverage1);
		System.out.println(beverage1.getDescription() + beverage1.cost());
		
	}

}
运行结果
DarkRoast2.0
HouseBlendMochaMilkSoy1.6000001
在看一个JDK里面的类图来帮助理解输入输出流 




















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值