首页 > 代码库 > Head First装饰模式(Decorator)

Head First装饰模式(Decorator)


装饰者模式是动态的将责任附加到另一个对象上,由这个对象负责;这个装饰与被装饰的组件接口一致,因此对使用该组件的客户透明;其中的关键点装饰者可以在所委托被装饰者的行为之前和之后,加上自己的行为,已达到特点的目的。

代码如下:
-------------Component
//装饰者模式一般使用抽象类
public abstract class Beverage {
     String description = "unknown beverage" ;
      public String getDescription(){
           return description ;
     }
     
      public abstract double cost();
}
------------Decorator(持有一个指向Component的指针,并与Component接口一致)
public abstract class CondimentDecorator extends Beverage{
      //要求所有的调料都要重新实现这个方法;
      public abstract String getDescription();
}
----------------ConcreteComponent(定义一些对象,可以给其添加职责)
//浓缩咖啡
public class Espresso extends Beverage{
      //为了重新设置饮料的描述,这里在构造方法中重置继承自基类的变量
      public Espresso(){
           description "Espresso" ;
     }
     
      public double cost() {
           return 1.99;
     }
}

//深焙咖啡
public class DarkRoast extends Beverage{
      public DarkRoast(){
           description "Dark Roast Coffee" ;
     }
     
      public double cost() {
           return 0.99;
     }
}

-------------ConcreteDecorator
//摩卡调料
public class Mocha extends CondimentDecorator{
     Beverage beverage ;
     
      //想办法让被装饰者(饮料)记录到实例变量中
      public Mocha(Beverage b){
           this .beverage = b;
     }
      //装饰者还要能描述其装饰的对象的特点
      @Override
      public String getDescription() {
           return beverage .getDescription() + ", Mocha";
     }

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

//豆浆调料
public class Soy extends CondimentDecorator{
     Beverage beverage;
     
      public Soy(Beverage b){
           this .beverage = b;
     }
      @Override
      public String getDescription() {
           return beverage .getDescription() + ", Soy";
     }

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

-----------------测试
public class StarbuzzCoffee {
      public static void main(String[] args) {
          Beverage b = new Espresso();
          System. out .println(b.getDescription() + ", $" +b.cost());
          Beverage b2 = new DarkRoast();
           b2 = new Mocha(b2 );
           b2 = new Mocha(b2 );
           b2 = new Soy(b2 );
          System. out .println(b2.getDescription() + ", $" +b2.cost());
     }
}