Javascript装饰器模式-原型还是单个函数? [英] Javascript Decorator Pattern - Prototype or single function?

查看:72
本文介绍了Javascript装饰器模式-原型还是单个函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在浏览有关装饰器模式的Addy Osmani的教程(在此处 http:// addyosmani。 com / blog / decorator-pattern / ),而我对如何在JavaScript中实现最简单的Decorator感到有些困惑。似乎有些示例使用obj.prototype模式向现有对象添加功能,有些示例创建独立的函数并传递对象。

I'm running through Addy Osmani's tutorial on The Decorator Pattern (found here http://addyosmani.com/blog/decorator-pattern/) and I'm a little confused on how to implement the most simplistic Decorator in Javascript. It seems that some examples use the obj.prototype pattern to add functionality to an existing object and some create a standalone function and pass an object.

// Decorator Pattern ?
function coffee(size, flavors) {
    this._size = size || "medium";
    this._flavors = flavors || [];   
    this._cost = 100;
    this.info = function() {
        console.log(this._size, this._flavors, this._cost);
    }
}

// Decorator - Would this be considered a decorator since the functionality needed to add flavors default to the coffee object?

function addFlavor(coffee, flavor) {
    coffee._flavors.push(flavor);
    coffee._cost = coffee._cost + 25;
}

// Decorator - Engrave the cup? lol
function engraving(coffee) {
    coffee._cost = coffee._cost + 200;
}

// Decorator Variation w/ prototype instead - Add cream
coffee.prototype.addCream = function () { 
    this._cost = this._cost + 100;
};

// Instantiate Coffee
testCoffee = new coffee('Large', ['vanilla']);

// Add Flavors
addFlavor(testCoffee, 'chocolate');
addFlavor(testCoffee, 'almond');
addFlavor(testCoffee, 'hazelnut');

// Add Engraving
engraving(testCoffee);

// Add Cream
testCoffee.addCream();

// Log it all to the console
testCoffee.info();

可以在此处找到此示例的JsFiddle: http://jsfiddle.net/pathsofdesign/ocbbzoy2/

A JsFiddle of this example can be found here: http://jsfiddle.net/pathsofdesign/ocbbzoy2/

我的问题:看来我可以使用原型继承来实现Decorator模式。以这种方式进行操作是否有任何利弊(即:我的addCream()方法)?
谢谢!

My question(s): It looks like I can implement the Decorator pattern using prototypal inheritance. Are there any pros or cons to doing it this way (Ie: my addCream() method)? Thanks!

更新:

似乎我的示例实际上并未实现Decorator模式。 @Etai和@Bergi都在下面给出了很好的答案。如果我理解正确,那么传统的JS Decorator会包装另一个obj,然后在不修改基础对象的情况下调整该特定对象的行为。

It looks like my example isn't actually implementing the Decorator pattern at all. Both @Etai and @Bergi gave great answers below. If I understand correctly, a traditional JS Decorator 'wraps' another obj and then makes adjustments to the behavior of that particular object without modifying the base object.

推荐答案

否您所拥有的没有装饰器,它们只是方法。方法确实会改变对象,装饰器会通过覆盖方法来改变行为。它们与 mixins 非常相似,只是它们不创建新方法。

No. What you have there are not decorators, they're just methods. Methods do mutate the object, decorators mutate behaviour by overwriting methods. They're quite similar to mixins, only that they don't create new methods.

例如,让我们给您咖啡类别 setSize 方法:

For example, let's give your Coffee class a setSize method:

Coffee.prototype.setSize = function(size) {
    this._size = size || 'medium';
};

现在,让我们来一个疯狂的咖啡师,他没有正确的比例:

Now, let's have a crazy barista who doesn't get proportions right:

function extreme(coffee) {
    var oldMethod = coffee.setSize;
    coffee.setSize = function(size) {
        oldMethod.call(this, size && 'Xtra'+size[0].toUpperCase()+size.slice(1));
    };
}

,然后让他为大订购:

> var coffee = extreme(new Coffee);
> coffee.setSize("large")
> coffee.info()
XtraLarge, Array [], 100

这篇关于Javascript装饰器模式-原型还是单个函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆