0

我正在用 Javascript 实现装饰器模式。

我在维基百科中看到了这个例子

// Class to be decorated
function Coffee() {
    this.cost = function() {
    return 1;
    };
}

// Decorator A
function Milk(coffee) {
    this.cost = function() {
    return coffee.cost() + 0.5;
    };  
}

// Decorator B
function Whip(coffee) {
    this.cost = function() {
    return coffee.cost() + 0.7;
    };
}

// Decorator C
function Sprinkles(coffee) {
    this.cost = function() {
    return coffee.cost() + 0.2;
    };
}

// Here's one way of using it
var coffee = new Milk(new Whip(new Sprinkles(new Coffee())));
alert( coffee.cost() );

// Here's another
var coffee = new Coffee();
coffee = new Sprinkles(coffee);
coffee = new Whip(coffee);
coffee = new Milk(coffee);
alert(coffee.cost());

现在我的问题是该模式仍然是装饰器模式,在 cost() 函数的开头或结尾调用父类是否重要?

现在,我意识到这取决于每个装饰器的作用......例如,如果你在装饰器中进行乘法或除法而不是加法或减法,它当然会保证不同的结果。

但是除了我在上一段中所说的原因之外,还有什么理由在之前或之后拨打电话吗?

4

4 回答 4

1

不要紧。装饰器应该改变一个对象的行为方式,它是如何做的纯粹是一个实现的问题。

于 2009-06-05T18:11:27.937 回答
1

您显然对编程很感兴趣,并且非常熟练,但请注意,谈论真实的任何事情都是危险的。编程很少有简单的答案,如果你认为你找到了答案,那么有人在利用你。

相反,只需尽可能多地学习工具,了解它们的优点和缺点,并知道它们何时合适以及何时需要修改。

于 2009-06-05T18:25:38.210 回答
0

小心

new X(new Y(new Z())))

类型结构。这有几个陷阱(我是一个 Java 人,所以我提到了几个 Java 示例,但这些概念确实适用于任何地方)

  • 您无权访问嵌套对象

    • 有时您需要它,例如,如果您正在装饰 Java IO 对象并且 close() 失败,您需要尝试关闭嵌套对象)
    • 有时您需要或想要设置额外的数据
    • 有时您需要从嵌套项 (new PrintWriter(new StringWriter()) 中获取结果——您需要从 StringWriter 获取结果字符串
  • 如果您遇到异常(或其他类型的错误),则很难根据报告的行号判断发生了什么

  • 调试时更难单步执行(取决于调试器)
  • 在中间插入东西更难
  • 中间的东西更难去掉
  • 重新安排订单更难
于 2009-06-05T19:12:52.877 回答
0

好的,找到了答案。

我回去重新阅读了我的设计模式书的装饰器模式部分,发现:

“装饰器在委托它装饰的对象之前和/或之后添加自己的行为以完成其余工作。”

重点是之前和/或之后......

很抱歉打扰您,感谢您的回答。

于 2009-06-07T23:44:15.763 回答