📜  Java的装饰器设计模式示例(1)

📅  最后修改于: 2023-12-03 15:16:37.220000             🧑  作者: Mango

Java的装饰器设计模式示例

装饰器设计模式是一种结构型设计模式,在不改变原有对象的前提下,通过包装或装饰的方式,动态地增加对象的功能和行为。在Java中,装饰器设计模式广泛应用于I/O流对象的处理,如BufferedInputStream、FileInputStream、InputStreamReader等。

下面通过一个示例来详细说明Java中的装饰器设计模式。

示例说明

假设我们要实现一个简单的饮料系统,包括三种饮料:Espresso、HouseBlend和DarkRoast。同时,我们希望能够动态地增加饮料的调料,如Mocha、Soy、Whip等。通过装饰器设计模式,我们可以在不改变原有饮料类结构的前提下,动态地增加调料。

类结构

首先看一下类结构图:

类结构图

在这个类结构中,抽象组件类(Beverage)是所有具体组件(Espresso、HouseBlend和DarkRoast)和装饰器类(CondimentDecorator)的父类。具体组件类和装饰器类都继承抽象组件类,从而具有相同的类型。

具体组件类是被装饰的原始对象,其包含一个描述饮料的变量(如description),以及计算价格的抽象方法(如cost())。

装饰器类是要动态增加的调料对象,其也包含一个描述饮料的变量(如description),同时也继承了抽象组件类的计算价格的抽象方法。此外,装饰器类包含一个指向具体组件的实例,可以通过构造函数传入。

代码实现

下面给出Java代码的实现细节,注意需要按照markdown标明代码片段。

抽象组件类(Beverage)
public abstract class Beverage {
    String description = "Unknown beverage";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}

在抽象组件类中,定义了描述饮料的变量和计算价格的抽象方法。

具体组件类(Espresso、HouseBlend和DarkRoast)
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 0.89;
    }
}

public class DarkRoast extends Beverage {
    public DarkRoast() {
        description = "Dark Roast Coffee";
    }

    public double cost() {
        return 0.99;
    }
}

在具体组件类中,通过覆盖抽象组件类中的描述变量和计算价格方法,实现了不同饮料的特性。

装饰器类(CondimentDecorator)
public abstract class CondimentDecorator extends Beverage {
    public abstract String getDescription();
}

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 0.20 + beverage.cost();
    }
}

public class Soy extends CondimentDecorator {
    Beverage beverage;

    public Soy(Beverage beverage) {
        this.beverage = beverage;
    }

    public String getDescription() {
        return beverage.getDescription() + ", Soy";
    }

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

public class Whip extends CondimentDecorator {
    Beverage beverage;

    public Whip(Beverage beverage) {
        this.beverage = beverage;
    }

    public String getDescription() {
        return beverage.getDescription() + ", Whip";
    }

    public double cost() {
        return 0.10 + beverage.cost();
    }
}

在装饰器类中,通过组合具体组件类实例的方式,实现对其动态增加调料功能。具体装饰器类中覆盖了getDescription()和cost()方法,通过在原有的描述字符串和价格上增加调料内容和价格,实现调料的动态增加。

调用示例

下面给出了一个示例调用代码:

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());

在调用示例中,首先创建了一个Espresso对象,并通过getDescription()和cost()方法输出其描述和价格。接着,创建了一个DarkRoast对象,并通过Mocha、Whip等装饰器对象,对其进行了多次动态调料操作,最终通过getDescription()和cost()方法输出其描述和价格。