【问题标题】:Decorator Design pattern issue装饰器设计模式问题
【发布时间】:2013-04-14 11:15:09
【问题描述】:

我正在为使用装饰器模式的正确性而苦苦挣扎。 让我们以暗黑破坏神2游戏为例。有一些物品(例如)剑,您可以用珠宝装饰,剑会发生变化,例如更多的攻击点或剑名修改。所以从这个角度来看,剑是一个可以被装饰的具体物体,而珠宝则是装饰者。但是珠宝也可以作为独立的、独立的物品保留,它们也有名称、描述和其他说明符。如何解决这个问题?我想要一个独立的“宝石”,可以得到他的名字,描述,但我也可以用这颗宝石装饰一些剑。请注意,jevel 和剑都有共同的说明符,例如独立的名称或描述。在用jevel装饰剑时,剑必须成为一个新名称,例如“sword with amethyst,而获得独立紫水晶的名称应该返回“an old amethyst”。有什么想法吗?

【问题讨论】:

    标签: design-patterns


    【解决方案1】:

    珠宝不应该是装饰器,因为它们不代表相同的功能,即剑。但是,您可以使用SwordWithJewels,或者使用伪代码:

    interface ISword { Stab(); }
    class Sword : ISword { Stab();  }
    class SwordWithJewels : ISword { Stab(); }
    

    SwordWithJewels 应该在构造过程中直接或间接通过拥有它们的另一个对象将珠宝作为参数,并使用该信息来计算命中强度或名称或您需要的任何内容。

    但请注意,这只是一个选项,根据上下文可能会有些过大。如果您将珠宝视为库存项目,那么使用其他方法可能更有意义(我故意避免使用模式一词,因为从“我需要为此使用某种模式”的想法开始通常会导致错误的代码)。只需遍历库存物品列表并让它们中的每一个从命中中添加或删除力量点也可能有意义,这更类似于访问者(如果您想要一个熟悉的名字)。

    【讨论】:

    • Sword 可以在这种情况下创作珠宝吗?
    • 嗯,关于在拥有原始剑的同时构建新的实例 SwordWithJewels 的想法是个坏主意,因为剑应该始终是相同的原始实例。如果我要在那里放一颗宝石,我不会创建一把新剑并将所有其他剑属性从“Sword”复制到“SwordWithJewels”。我认为它扰乱了面向对象的编程概念,你不觉得吗?一把剑应该总是相同的剑实例,有或没有珠宝。其次,当创建一个新的 SwordWithJewels 实例时,程序会处理 2 个不同的剑实例,而在游戏中应该只存在一个
    • 错了。这就是装饰器模式的重点:让一个对象包装另一个对象,并通过增强的功能公开相同的接口。这也是我暗示装饰器在这里是一个糟糕选择的原因。不要为了符合文献而选择模式。在有意义时使用它们。
    • 对不起,我不明白你的回答,你能再详细点吗?在我之前的帖子中,我在谈论您使用“Sword”和“SwordWithJewels”的解决方案,而不是关于装饰器模式,所以我在之前的帖子和您的最后一个答案之间没有看到任何联系。
    • 您提到有两个对象等 - 装饰器是关于包装对象的,因此您将有多个实例在它们之间转发调用。尽管您在最后一条评论中没有提到它,但您的问题的标题是“装饰器……”。联系是您不能考虑多个对象是个坏主意,同时仍然在装饰器主题上。话虽如此,多个对象没有问题 - 它们仅在构造时可见,之后客户端只处理一个对象。
    猜你喜欢
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    • 2020-05-13
    • 2016-10-05
    • 1970-01-01
    • 1970-01-01
    • 2013-11-28
    相关资源
    最近更新 更多