设计模式(009)结构型之装饰器模式

装饰器模式允许在运行时向对象添加功能,避免使用继承带来的静态扩展。文中通过咖啡制作的例子,展示了如何使用C++和Java实现装饰器模式,包括抽象组件、具体组件、抽象装饰器和具体装饰器的角色及其交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        装饰器模式(Decorator Pattern)允许在运行时动态地向对象添加功能,而无需修改其源代码。在该模式中,有一个被装饰的对象(Component),它定义了一些基本的操作。装饰器(Decorator)对象是对这个基本对象的一个包装,可以在不改变其接口的情况下,为其添加新的行为或修改现有的行为。
        通过使用装饰器模式,可以避免使用继承带来的静态扩展,而使用对象组合的方式来动态扩展对象的行为。这种方式也可以避免创建大量的子类,从而提高代码的可维护性和灵活性。
        装饰器模式的组件包括:抽象组件(Component)、具体组件(ConcreteComponent)、抽象装饰器(Decorator)和具体装饰器(ConcreteDecorator)。
        抽象组件(Component)定义了基本的操作,具体组件(ConcreteComponent)实现了基本操作。抽象装饰器(Decorator)也是一个抽象组件,它持有一个被装饰的对象,并定义了一个与抽象组件一样的接口。具体装饰器(ConcreteDecorator)实现了具体的装饰行为,并在其中调用被装饰对象的方法。
        装饰器模式的优点在于它可以动态地添加或删除对象的功能,而且具有灵活性和可扩展性。它可以避免使用继承带来的静态扩展,并且能够避免在代码中创建大量的子类。缺点在于,如果有太多的装饰器,代码可能会变得复杂。

1、场景设计

实现场景:调制两杯咖啡。一杯是独立的浓缩咖啡,一杯是深度烘焙咖啡加两层摩卡和一层奶泡。

2、C++实现

#include <iostream>
#include <string>

// 抽象组件
class Beverage {
public:
    virtual std::string getDescription() = 0;
    virtual double getCost() = 0;
};

// 具体组件:浓缩咖啡
class Espresso : public Beverage {
public:
    std::string getDescription() override {
        return "Espresso";
    }
    double getCost() override {
        return 1.99;
    }
};

// 具体组件:深度烘焙咖啡
class DarkRoast : public Beverage {
public:
    std::string getDescription() override {
        return "Dark Roast Coffee";
    }
    double getCost() override {
        return 0.99;
    }
};

// 抽象装饰器
class CondimentDecorator : public Beverage {
public:
    virtual std::string getDescription() = 0;
};

// 具体装饰器:加摩卡且售价加0.2
class Mocha : public CondimentDecorator {
public:
    Mocha(Beverage* beverage) {
        this->beverage = beverage;
    }
    std::string getDescription() override {
        return beverage->getDescription() + ", Mocha";
    }
    double getCost() override {
        return 0.20 + beverage->getCost();
    }
private:
    Beverage* beverage;
};

// 具体装饰器:加奶泡且售价加0.1
class Whip : public CondimentDecorator {
public:
    Whip(Beverage* beverage) {
        this->beverage = beverage;
    }
    std::string getDescription() override {
        return beverage->getDescription() + ", Whip";
    }
    double getCost() override {
        return 0.10 + beverage->getCost();
    }
private:
    Beverage* beverage;
};

int main() {
    Beverage* beverage = new Espresso();
    std::cout << beverage->getDescription() << " $" << beverage->getCost() << std::endl;

    Beverage* beverage2 = new DarkRoast();
    beverage2 = new Mocha(beverage2);
    beverage2 = new Mocha(beverage2);
    beverage2 = new Whip(beverage2);
    std::cout << beverage2->getDescription() << " $" << beverage2->getCost() << std::endl;

    delete beverage;
    delete beverage2;

    return 0;
}

3、Java实现

DecoratorDemo.java

package structuralpattern.decorator;

// 抽象组件
interface Beverage {
    String getDescription();
    double getCost();
}
// 具体组件:浓缩咖啡
class Espresso implements Beverage {
    @Override
    public String getDescription() {
        return "Espresso";
    }
    @Override
    public double getCost() {
        return 1.99;
    }
}
// 具体组件:深度烘焙咖啡
class DarkRoast implements Beverage {
    @Override
    public String getDescription() {
        return "Dark Roast Coffee";
    }
    @Override
    public double getCost() {
        return 0.99;
    }
}

// 抽象装饰器
abstract class CondimentDecorator implements Beverage {
    protected Beverage beverage;
    public CondimentDecorator(Beverage beverage) {
        this.beverage = beverage;
    }
    @Override
    public String getDescription() {
        return beverage.getDescription();
    }
    @Override
    public double getCost() {
        return beverage.getCost();
    }
}

// 具体装饰器:加摩卡且售价加0.2
class Mocha extends CondimentDecorator {
    Mocha(Beverage beverage) {
        super(beverage);
    }
    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Mocha";
    }
    @Override
    public double getCost() {
        return 0.20 +  beverage.getCost();
    }
}

// 具体装饰器:加奶泡且售价加0.1
class Whip extends CondimentDecorator {
    Whip(Beverage beverage) {
        super(beverage);
    }
    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Whip";
    }
    @Override
    public double getCost() {
        return 0.10 +  beverage.getCost();
    }
}

public class DecoratorDemo {
    public static void main(String[] args){
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription() + " $" + beverage.getCost());
        Beverage beverage2 = new DarkRoast();
        beverage2 = new Mocha(beverage2);
        beverage2 = new Mocha(beverage2);
        beverage2 = new Whip(beverage2);
        System.out.println(beverage2.getDescription() + " $" + beverage2.getCost());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值