Head First设计模式学习笔记-------(3)装饰者模式

在本章你将学到如何使用对象组合方式,做到在运行时装饰类。


今天我们项目例子是一家咖啡店,让我们先来看看这个项目的类图吧。


购买咖啡时,也可以加入各种调料,服务员会根据加入的调料收取不同的费用,所以订单系统必须考虑到这些调料部分。

让我们来看一下下面这种设计结构。



是不是看了上面这个结构,虽然不知道怎么样,但是总感觉有什么问题对吧,让我们来看看上面这个结构存在什么问题吧。

1:调料价钱的改变会使我们更改现有代码。

2:一旦出现新的调料,我们就需要加上新的方法,并改变超类中的cost()方法。

3:以后可能会开发出新饮料,某些调料可能并不合适,但是在这个设计方式中,子类仍将继承那些不合适的方法。

我们就先列举一些问题,当然还有其他问题小伙伴们可以自己去挖掘哦。

到了这里,我们就要提出一个非常重要的设计原则了:

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

接下来让我们看下装饰者模式是怎么样的吧:



是不是一下子就明白怎么回事了,我们来介绍一下装饰者模式的一些概念吧:

1:装饰者和被装饰对象有相同的超类型。

2:你可以用一个或多个装饰者包装一个对象。

3:既然装饰者和被装饰对象有相同的超类型,所以在任何需要原始对象的场合,可以用装饰过的对象代替它。

4:装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的。

5:对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来修饰对象。

装饰者模式定义:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

装饰者模式类图:


利用装饰者模式后项目的类图:


接下来我们就要开始实现我们的具体代码了。

Beverage类:

public abstract class Beverage {
	String description = "Unknown Beverage";

	public String getDescription() {
		return description;
	}
	
	public abstract double cost();

}
CondimentDecorator类:
public abstract class CondimentDecorator extends Beverage{
	
	public abstract String getDescription(); //所有的调料装饰者都必须重新实现getDescription方法

}
Espresso类:
public class Espresso extends Beverage{
	
	public Espresso(){
		description = "Espresso";
	}
	
	public double cost(){
		return 1.99;
	}

}
HouseBlend类:
public class HouseBlend extends Beverage{
	
	public HouseBlend(){
		description = "House Blend Coffee";
	}
	
	public double cost(){
		return 0.89;
	}

}
这里我们就列举2种咖啡,其他的就不一一写出来了。
接下来我们来写调料

Mocha类:

public class Mocha extends CondimentDecorator{
	Beverage beverage;           //用一个实例变量来记录饮料,也就是被装饰者
	
	public Mocha(Beverage beverage) {
		this.beverage = beverage;     //让被装饰者被记录到实例变量中
	}
	
	public String getDescription() {
		return beverage.getDescription() + ", Mocha";
	}
	
	public double cost() {
		return 0.20+beverage.cost();   //返回计算后的价格
	}

}
其他的调料也基本是这个结构。

还记得上一章我们说过,java API里面有内置的观察者模式,其实装饰者模式也是一样的,java API也为我们提供了,那就是java I/O。


这里就不具体说明这个API的用法了,下面我们总结下这一章的内容:

1:继承属于扩展形式之一,但不见得是达到弹性设计的最佳方式。

2:在我们的设计中,应该允许行为可以扩展,而无须修改现有的代码。

3:组合和委托可用于在运行时动态地加上新的行为。

4:除了继承,装饰者模式也可以让我们扩展行为。

5:装饰者模式以为着一群装饰者类,这些类用来包装具体组件。

6:装饰者类反应出被装饰的组件类型。

7:装饰者可以在被装饰者的行为前面与/或后面加上自己的行为,甚至将被装饰者的行为整个取代掉,而达到特定的目的。

8:可以用无数个装饰者包装一个组件。

9:装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。

10:装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值