装饰者模式

装饰者模式:动态的将额外的责任添加到对象上去,相对于继承,提供更加灵活的扩展方案。

装饰者模式,有4个抽象的类概念:

  1. 抽象构建类:被装饰对象的接口
  2. 具体的构建类:被装饰的对象
  3. 抽象装饰者:怎么进行装饰的接口
  4. 具体装饰者:具体装饰的对象

关系类图如下:
关系类图
其中重点是:抽象装饰者接口继承了被装饰对象的接口,这点非常重要,它是能够进行动态装饰的关键,根据接口动态的去匹配具体构件类。

举例:
咖啡店原本提供有2种咖啡:CoffeeDarked深焙咖啡、CoffeeMixed混合咖啡,先需要在这2中咖啡中可以添加:Milk牛奶、Mocha摩卡。
思考:
思考
按照上图分析结果,可以调出6中不同口味的咖啡。如果按照继承的逻辑,一种咖啡可能需要建立一个子类(或者实现类),此处就需要建6个子类。如果需要添加的不止牛奶和摩卡2种,那子类将非常庞大。

如果使用装饰者模式,就不需要建立6个子类,只需要建立2种具体装饰者类(Milk、Mocha),即可满足需求。

下面是代码实现:()
1)抽象构件类

/**
 * 抽象构件类
 * @author Administrator
 *
 */
public interface Coffee {
  /**
   * 描述什么样的咖啡
   * @return
   */
  public abstract String getDescription();
  
  /**
   * 计算咖啡的价格
   * @return
   */
  public abstract double count();
}

2)具体构件类

/**
 * 具体构件类:深焙咖啡
 * @author Administrator
 *
 */
public class CoffeeDarked implements Coffee {

  @Override
  public String getDescription() {
    return "深焙咖啡";
  }

  @Override
  public double count() {
    return 10;
  }
}
/**
 * 具体构建类:混合咖啡
 * @author Administrator
 *
 */
public class CoffeeMixed implements Coffee {

  @Override
  public String getDescription() {
    return "混合咖啡";
  }

  @Override
  public double count() {
    return 20;
  }
}

3)抽象装饰者类

/**
 * 咖啡装饰者接口
 * @author Administrator
 *
 */
public interface DecoratorCoffee extends Coffee {

  public abstract String getDescription();
  
}

4)具体装饰者类

/**
 * 具体装饰者:加牛奶
 * @author Administrator
 *
 */
public class DecoratorMilk implements DecoratorCoffee {
  
  private Coffee coffee;
  
  public DecoratorMilk(Coffee coffee){
    this.coffee = coffee;
  }

  @Override
  public double count() {
    
    return coffee.count() + 5;
  }

  @Override
  public String getDescription() {
    return coffee.getDescription() + "加牛奶";
  }
}
/**
 * 具体装饰者类:加摩卡
 * @author Administrator
 *
 */
public class DecoratorMocha implements DecoratorCoffee {
  
  private Coffee coffee;
  
  public DecoratorMocha(Coffee coffee){
    this.coffee = coffee;
  }

  @Override
  public String getDescription() {
    return coffee.getDescription() + "加摩卡";
  }

  public double count() {
    return coffee.count() + 2;
  }
}

最后测试下:

public class DecoratorTest {

  /**
   * @param args
   */
  public static void main(String[] args) {
    
    //想要一杯混合咖啡
    Coffee coffee1 = new CoffeeMixed();
    System.out.println(coffee1.getDescription() + " " + coffee1.count());
    
    // 想要一杯加牛奶的混合咖啡(对coffee1进行装饰,加上牛奶)
    Coffee coffee2 = new DecoratorMilk(coffee1);
    System.out.println(coffee2.getDescription() + " " + coffee2.count());
    
    // 想要一杯加摩卡加牛奶的深焙咖啡
    Coffee coffee3 = new CoffeeDarked();
    coffee3 = new DecoratorMilk(coffee3);
    coffee3 = new DecoratorMocha(coffee3);//进一步对加了牛奶的咖啡加上摩卡
    System.out.println(coffee3.getDescription() + " " + coffee3.count());
  }
}

测试结果:
在这里插入图片描述

总结:
装饰者模式能实现动态的对对象进行扩展,主要有2点,一是,抽象装饰者类和具体的构建类有相同的接口,二是具体的装饰者类和抽象构建类之间有依赖(具体在UML中怎么称呼不太了解,之后在补习下),并且通过构造器依赖注入,在运行时,就根据具体的实现类注入了。这样就实现了对象动态扩展。

装饰者模式和代理模式的区别:
代理模式:给对象创建一个代理对象,由代理对象代替对象进行操作。
装饰者模式:对对象进行功能的扩展。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值