读《Head First Design Patterns》(第三章 装饰者模式)

第3章讲了装饰者模式,书中列举了一个星巴克咖啡的例子,比较浅显的阐述了这种模式。我将力求提取其中实际的部分,并消化之,作此记录,以供日后参考。 先从一条金科玉律(Open-Closed Principle)开始吧:

Classes should be open for extension,but closed for modification

我的理解是类的设计应该做到有新的变化易于扩展但对原有的代码不能有修改。

这当然好啦,只是听起来似乎挺矛盾的,也不知道该怎么实现。但的确有相应的OO技巧,等着瞧吧。先看一下书里有段话值得我们注意,特别象我这种不懂OO的OO崇拜者:

applying the Open-Closed Principle EVERYWHERE is wasteful, unnecessary, and can lead to complex, hard to understand code.

Following the Open-Closed Principle usually introduces new levels of abstraction,which adds complexity to our code.You want to concentrate on those areas that are most likely to change in your designs and apply the principles there.

好了,现在我们来正视观察者模式是如何实现这个原则的:

装饰者模式定义:The Decorator Pattern attaches additional
responsibilities to an object dynamically.Decorators provide a flexible alternative to subclassing for extending functionality.

看看书中的例子:

代码如下:

Beverage.java

package com.Decorator.www;

public abstract class Beverage {

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

}

 public abstract String getDescription();

}

 

DarkRoast.java

package com.Decorator.www;

public class DarkRoast extends Beverage {
 
 public DarkRoast(){
  
  super.description = "description";
 }
 public double cost() {
  // TODO 自动生成方法存根
  return .78;
 }

}

 

Mocha.java

package com.Decorator.www;

public class Mocha extends CondimentDecorator {

 Beverage beverage;
 public Mocha(Beverage beverage) {
  this.beverage = beverage;
 }
 
 public String getDescription() {
  // TODO 自动生成方法存根
  return beverage.getDescription() + ", Mocha";
 }

 public double cost() {
  // TODO 自动生成方法存根
  return .20 + beverage.cost();
 }

}

StarbuzzCoffee.java

package com.Decorator.www;

public class StarbuzzCoffee {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO 自动生成方法存根
  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 Soy(beverage3);
  beverage3 = new Mocha(beverage3);
  beverage3 = new Whip(beverage3);
  System.out.println(beverage3.getDescription()
  + "$" + beverage3.cost());
 }

}

其他略

没错,就是包装者模式,需要添加一个新功能就包一层,同时需要另外一个新功能就再包一层。基本的原理是这样的:如果需要对A类装饰,就从A类的父类继承一个装饰者虚拟类(当然也可以用接口,可能接口更理想),然后从这个虚拟类(接口)实现具体的装饰者类,在具体装饰者类中从构造函数引入被包装者对象,然后对该对象添加额外的功能。(The decorator adds its own behavior either before and/or after delegating to the object itdecorates to do the rest of the job.)这样很容易就扩展了被包装类的功能,也没有修改被包装类和他的父类。

装饰者模式很好的弥补了继承的不足之处,可以真正的做到Open-Closed Principle原则,不过也有不足的一面:

1.sometimes add a lot of small classes to a design and this occasionally results in a design that’s less than straightforward for others to understand.

2.you can usually insert decorators transparently and the client never has to knowit’s dealing with a decorator

关于这些我也只是字面理解,在以后的实际应用中慢慢体会吧!

 

posted @ 2006-02-25 08:56  红心李  阅读(111)  评论(0编辑  收藏  举报