《深入浅出设计模式》 笔记第三章 装饰者模式

《深入浅出设计模式》 笔记第三章 装饰者模式

有这么一个需求:咖啡厅做饮料。饮料分基础饮料(浓缩咖啡、普通咖啡等等)和调味饮料(果汁、豆浆等)。现要求建立一个系统,计算饮料的价格和饮料的描述,成品饮料会在基础饮料的上搭配调味饮料。

《深入浅出设计模式》 笔记第三章 装饰者模式_第1张图片

第一次尝试

《深入浅出设计模式》 笔记第三章 装饰者模式_第2张图片

很明显,这种实现很烂。

第二次尝试

《深入浅出设计模式》 笔记第三章 装饰者模式_第3张图片

该次尝试将调味饮料放在了超类的属性(布尔值)中,每加入一种调味饮料,就需要添加一个属性和Get、Set方法。

但这种尝试违反了开放-关闭原则。

开放-关闭原则

设计原则:类应该对扩展开放,对修改关闭。

在选择需要被扩展的代码部分时要小心。每个地方都采用开放-关闭原则,是一种浪费,也没有必要,还会导致代码变得复杂且难以理解。

装饰者模式

装饰者模式下的系统,层层装饰:

《深入浅出设计模式》 笔记第三章 装饰者模式_第4张图片

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

装饰者模式的特点:

  • 装饰者和被装饰者对象有相同的超类型
  • 可以用一个或多个装饰者包装一个对象
  • 既然装饰者和被装饰者对象有相同的超类型,所以在任何需要原始对象(被包装的)的场合,可以用装饰过的对象替代它
  • 装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的
  • 对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用需要地装饰者来装饰对象

装饰者模式的类图:

《深入浅出设计模式》 笔记第三章 装饰者模式_第5张图片

##装饰者模式下的系统

类图:

《深入浅出设计模式》 笔记第三章 装饰者模式_第6张图片

代码实现

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

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}
public abstract class CondimentDecorator extends Beverage {
    public abstract String getDescription();
}
public class Espresso extends Beverage {
    public Espresso() {
        description = "Espresso";
    }
    
    public double cost() {
        return 1.99;
    }
}
public class HouseBlend extends Beverage {
    public HouseBlend() {
        description = "House Blend Coffee";
    }

    public double cost() {
        return .89;
    }
    
}
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 .20 + beverage.cost();
    }
}
public class Test {
    public static void main(String[] args) {
        Beverage beverage = new Espresso();
        System.out.println(beverage.description + " $" + beverage.cost());

        Beverage beverage2 = new HouseBlend();//被装饰
        beverage2 = new Mocha(beverage2);//装饰者
    }
}

真实世界的装饰者:Java I/O

《深入浅出设计模式》 笔记第三章 装饰者模式_第7张图片

装饰者模式的“缺点”:

  • 利用装饰者模式,常常造成设计中有大量的小类,数量很多,可能会造成使用此API程序员的困扰
  • 类型问题:有些代码会依赖特定的类型,却没有考虑周全
  • 采用装饰者在实例化组件时,将增加代码的复杂度

你可能感兴趣的:(设计模式,设计模式,java)