设计模式专题之C语言-装饰者模式

1.简介

装饰者模式(Decorator Pattern)是一种结构型设计模式,它允许向对象动态地添加新的功能。这种模式通过创建一个装饰类来包装原有的类,可以在不修改原类的基础上给类添加新的职责。

适用场景

  • 当需要扩展一个类的功能或者给一个类添加附加职责时,装饰者模式提供了一种比继承更加灵活的方式。
  • 当不能采用生成子类的方法进行扩充时,一种情况是系统中存在大量的独立扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。
  • 另一种情况可能是因为类定义被隐藏,或类定义经过精心设计,如被做成最终类(final class)等方式,不能被继承。

2.通俗讲解

想象一下,你经营着一家咖啡店,基本的产品是“咖啡”,但是顾客还可以选择添加不同的配料(比如牛奶、糖等),这些配料可以自由组合。我们可以通过装饰者模式来实现这样的功能。

3.实战

  1. 定义抽象组件接口:这是所有实体和装饰者的共同接口。
  2. 创建具体组件:实现抽象组件接口,代表具体的基本功能。
  3. 创建抽象装饰器:实现抽象组件接口,并持有具体组件的实例。
  4. 创建具体装饰器:继承自抽象装饰器,负责添加新行为。

3.1.代码

#include <stdio.h>
#include <stdlib.h>

// 定义抽象组件接口
typedef struct Component {
    int cost;
} Component;

// 定义抽象装饰器
typedef struct Decorator {
    Component *component;
} Decorator;

// 具体组件: 咖啡
typedef struct Coffee {
    Component base;
} Coffee;

// 具体装饰器: 牛奶
typedef struct MilkDecorator {
    Decorator base;
} MilkDecorator;

// 具体装饰器: 糖
typedef struct SugarDecorator {
    Decorator base;
} SugarDecorator;

// 初始化咖啡
Coffee* createCoffee() {
    Coffee *coffee = (Coffee *)malloc(sizeof(Coffee));
    coffee->base.cost = 10; // 假设基础咖啡的价格是10元
    return coffee;
}

// 初始化牛奶装饰器
MilkDecorator* createMilkDecorator(Component *coffee) {
    MilkDecorator *milkDecorator = (MilkDecorator *)malloc(sizeof(MilkDecorator));
    milkDecorator->base.component = coffee;
    milkDecorator->base.component->cost += 5; // 添加牛奶后价格增加5元
    return milkDecorator;
}

// 初始化糖装饰器
SugarDecorator* createSugarDecorator(Component *coffee) {
    SugarDecorator *sugarDecorator = (SugarDecorator *)malloc(sizeof(SugarDecorator));
    sugarDecorator->base.component = coffee;
    sugarDecorator->base.component->cost += 2; // 添加糖后价格增加2元
    return sugarDecorator;
}

int main() {
    Coffee *coffee = createCoffee();
    printf("Basic Coffee Cost: %d\n", coffee->base.cost);

    MilkDecorator *milkCoffee = createMilkDecorator((Component *)coffee);
    printf("Coffee with Milk Cost: %d\n", milkCoffee->base.component->cost);

    SugarDecorator *sugarCoffee = createSugarDecorator((Component *)coffee);
    printf("Coffee with Sugar Cost: %d\n", sugarCoffee->base.component->cost);

    SugarDecorator *milkSugarCoffee = createSugarDecorator((Component *)milkCoffee);
    printf("Coffee with Milk and Sugar Cost: %d\n", milkSugarCoffee->base.component->cost);

    free(coffee);
    free(milkCoffee);
    free(sugarCoffee);
    free(milkSugarCoffee);

    return 0;
}

3.2.代码解析

  1. 创建一个基本的咖啡对象,其成本为10元。
  2. 创建一个带有牛奶的咖啡对象,其成本为基本咖啡成本加上牛奶的成本5元。
  3. 创建一个带有糖的咖啡对象,其成本为基本咖啡成本加上糖的成本2元。
  4. 创建一个既带有牛奶又带有糖的咖啡对象,其成本为带有牛奶的咖啡成本再加上糖的成本2元。

通过装饰者模式,我们能够在不改变原始咖啡对象的情况下,为其动态地添加新的特性(即不同的配料)。这种方式提供了很好的灵活性,并且避免了使用多个继承带来的复杂性和维护上的困难。

3.3.代码运行

Basic Coffee Cost: 10
Coffee with Milk Cost: 15
Coffee with Sugar Cost: 12
Coffee with Milk and Sugar Cost: 17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甜航一直在

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值