装饰者模式(讲解生动形象图文并茂)

在说装饰者模式之前,先来说一个重要的设计原则:

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

遵循了这个原则,我们的类将会容易扩展,在不修改现有代码的情况下,我们可以搭配新的行为,这样的设计具有弹性,可以接受新的功能来应对改变的需求。

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

接下来,我们以一个卖咖啡的例子来讲解。

在咖啡店,有各种不同的咖啡,都有不同的价格,如黑咖啡(Espresso)售价1.99,客户还可以加不同的调料,不同的调料价格不同。在这个背景下,如果让我们来设计,可能会想到为每一种咖啡配每一种调料设计一个类,然后计算价格,这样的话情况会非常复杂,而且万一我想加两份牛奶呢?这时候,就让我们看一下装饰者模式。

先看一个图:

装饰者模式(讲解生动形象图文并茂)_第1张图片

1.装饰者和被装饰者有相同的超类型,我们利用继承达到“类型匹配”,方便调用,而不是利用继承获得行为。

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

了解了装饰者模式,接下来要编写代码,也是关于咖啡店的,先看一个简单的类图。

装饰者模式(讲解生动形象图文并茂)_第2张图片

代码:

Coffee.java  抽象的超类,各种类型的咖啡和调料都继承这个超类。

package com.decorator;
//抽象组件类
public abstract class Coffee {

    protected String description = "Unknown Coffee";

    public String getDescription(){
        return this.description;
    }

    public abstract double cost();
}


Espresso.java  具体的子类,是具体的被装饰者

package com.decorator;
//黑咖啡,是coffee的子类,也就是具体组件类
public class Espresso extends Coffee {

    public  Espresso(){
        this.description = "Espresso";
    }

    public double cost(){
        return 1.99;
    }
}
CondimentDecorator.java

package com.decorator;
//调料,继承超类的装饰者抽象类,为了达到“类型匹配”,而不是为了获得行为
public abstract class CondimentDecorator extends Coffee {
    //所有的调料装饰者都必须重新实现这个方法,因为装饰者的description是要要修饰被装饰者的description的
    public abstract String getDescription();
}

Milk.java
package com.decorator;
//装饰者类
public class Milk extends CondimentDecorator {

    private Coffee coffee;

    public Milk(Coffee coffee){
        this.coffee = coffee;
    }

    public String getDescription(){//重写该方法,
        return coffee.getDescription() + ", Milk";
    }
    //从装饰者开始调用,一路调用,计算钱
    public double cost(){
        return 0.2 + coffee.cost();
    }
}

测试类:
package com.decorator;

public class StarbuzzCoffee {

    public static void main(String[] args) {
        Coffee coffee = new Espresso();
        System.out.println(coffee.getDescription() + " " + coffee.cost());

        Coffee coffee1 = new Espresso();
        coffee1 = new Milk(coffee1);//加一份牛奶
        System.out.println(coffee1.getDescription() + " " + coffee1.cost());
    }
}

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