【问题标题】:C decorator design pattern (using the pizza example)C 装饰器设计模式(使用比萨饼示例)
【发布时间】:2016-06-30 01:08:24
【问题描述】:

我正在学习嵌入式系统的低级课程,并被分配了在 C 中复制一些设计模式的任务。我已经让观察者和委托者工作了我真的在为装饰器模式苦苦挣扎。我确实意识到很多人认为设计模式不属于像 C 这样的“低级”语言,但我没有选择 - 需要完成这门课程才能通过。我找到的所有示例都是针对 OO 编程语言的。我使用这个 Java 披萨示例作为基础(只是返回成本以使其变得容易)但对于我的生活来说无法让它工作:http://www.newthinktank.com/2012/09/decorator-design-pattern-tutorial/

这是示例的 UML(正如我所说,我只做 getCost 部分):

我花了大约 2 天的时间试图让它工作,但只是卡住了。我已经添加了我拥有的代码,但我很难过如何将番茄添加到比萨饼中,以便正确添加成本

#include <stdio.h>

typedef struct _pizza {
    double (* getCost) ();
} pizza_t;

typedef struct _toppingDecorator {
    double (* getCost) ();
    pizza_t tempPizza;
} toppingDecorator_t;

// these are the pizzas
double plainPizzaCost () {
    return 5;
}
double thickCrustPizzaCost () {
    return 7;
}

// these are the toppings
double mozzarellaCost (toppingDecorator_t * self) {
    return self->tempPizza.getCost () + 3.0;
}
double tomatoCost (toppingDecorator_t * self) {
    return self->tempPizza.getCost () + 1;
}

int main(int argc, const char * argv[]) {

    pizza_t plainPizza;
    plainPizza.getCost = &plainPizzaCost;

    pizza_t thickCrustPizza;
    thickCrustPizza.getCost = &thickCrustPizzaCost;

    toppingDecorator_t mozzarella;
    mozzarella.tempPizza = plainPizza;
    mozzarella.getCost = &mozzarellaCost;

    toppingDecorator_t tomato;
    tomato.tempPizza = mozzarella.tempPizza;
    tomato.getCost = &tomatoCost;

    // now print the cost
    printf ("A plain pizza costs %f\n", plainPizza.getCost ());
    printf ("A mozzarella pizza costs %f\n", mozzarella.getCost (&mozzarella));
    printf ("A tomato and mozzarella pizza costs %f\n", tomato.getCost (&mozzarella));
}

【问题讨论】:

  • 多么可怕的模式:)
  • 我知道,我知道...但我们需要这样做:)

标签: c design-patterns


【解决方案1】:

不知道为什么这个帖子被否决了,但无论如何......一个朋友为我解决了这个问题,我想我会在这里发布答案 - 谢谢你 Marcel :o)

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

typedef struct _pizza pizza_t;
typedef double (* getCost)(struct _pizza * self);

typedef struct _pizza {
    getCost getCostFunc;
} pizza_t;

typedef struct _plainPizza {
    pizza_t base;
} plainPizza_t;

typedef struct _toppingDecorator {
    pizza_t base;
    pizza_t * decorate;
} toppingDecorator_t;

// these are the pizzas
double plainPizzaCost (plainPizza_t self) {
    return 5;
}

// these are the toppings
double mozzarellaCost (toppingDecorator_t * self) {
    return self->decorate->getCostFunc(self->decorate) + 3;
}
double tomatoCost (toppingDecorator_t * self) {
    return self->decorate->getCostFunc(self->decorate) + 2;
}
double salamiCost (toppingDecorator_t * self) {
    return self->decorate->getCostFunc(self->decorate) + 1;
}

int main(int argc, const char * argv[]) {

    plainPizza_t plainPizza;
    plainPizza.base.getCostFunc = (getCost) plainPizzaCost;

    toppingDecorator_t mozzarella;
    mozzarella.base.getCostFunc = (getCost) mozzarellaCost;
    mozzarella.decorate = (pizza_t *) &plainPizza;

    toppingDecorator_t tomato;
    tomato.base.getCostFunc = (getCost) tomatoCost;
    tomato.decorate = (pizza_t *) &mozzarella;

    toppingDecorator_t salami;
    salami.base.getCostFunc = (getCost) salamiCost;
    salami.decorate = (pizza_t *) &tomato;

    printf ("A tomato pizza costs %f\n", tomato.base.getCostFunc((pizza_t *) &tomato));
    printf ("A salami pizza costs %f\n", salami.base.getCostFunc((pizza_t *) &salami));
}

【讨论】:

  • 这是装饰器模式吗?原因:应该可以使用相同的装饰器两次或多个装饰器。这可以制作像番茄+意大利腊肠这样的比萨吗?我在上面的例子中看不到这种可能性,因为我们只能制作番茄或马苏里拉奶酪,但不能同时制作。
  • 嗨,斯里卡。老实说,我无法回答你的问题。我早就学完了课程,不再用C了?
猜你喜欢
  • 1970-01-01
  • 2013-12-06
  • 2010-10-05
  • 1970-01-01
  • 1970-01-01
  • 2021-04-27
  • 2013-11-28
  • 1970-01-01
相关资源
最近更新 更多