【问题标题】:Properly encapsulate array collection正确封装数组集合
【发布时间】:2011-12-22 02:20:42
【问题描述】:

您好,我的任务是构建一个具有以下简介的应用程序。

实现一个接口,根据促销规则计算价格。

co = Checkout.new(promotional_rules)
co.scan(item)
co.scan(item)
price = co.total

基本上,根据设置的促销规则,某些商品会相应打折。

我收到了一些关于我的代码的反馈,指出我已经封装了一组promotion_rules,然后将这些规则公开为一个数组——糟糕的OO

我最初创建了一个promotion_rules 对象,其中包含一组规则。

  def initialize
    @rules = []
  end

 def addrule(rule)
   @rules.push(rule)
 end

然后在我的结帐对象中,我有已设置并传递给初始化程序的promotion_rules 对象。我遍历包含在promotion_rules 对象中的规则数组,并将它们应用于结帐对象扫描的项目。

def initialize(promotionalrules=Promotionalrules.new)
  @promotionalrules = promotionalrules
end

....Other code

for rule in @promotionalrules.getrules
  for item in @items
    ##Execute rule on current item.
  end
end

我对我的代码不太满意...循环与循环等。但我只是在寻找一些关于封装的帮助,因为我不确定我哪里出错了。

任何关于适用于简报的良好设计模式的建议也将是有益的,因为我对我采用的方法不太自信。谢谢

【问题讨论】:

    标签: ruby oop design-patterns encapsulation


    【解决方案1】:

    我猜他们是在抱怨这种“曝光”:

    for rule in @promotionalrules.getrules
    

    这会将促销规则(可能应该称为 PromotionalRules)中的内部规则泄露给调用者。解决方法是稍微颠倒你的逻辑:

    class Promotionalrules
      #...
      # and possibly remove the getrules method completely
      def apply_to_item(item)
        # Apply @rules to item
      end
      #...
    end
    

    然后:

    # I'm not sure how the rules and item interact so this "each" might
    # be a different iterator in reality
    @items.each { |i| @promotional_rules.apply_to_item(i) }
    

    基本的变化是您将规则集作为一个整体应用于每个项目。这隐藏了规则集的实施细节,并且作为额外的奖励,允许您轻松支持相互依赖的规则(“除非您使用优惠券 Y,否则您可以获得折扣 X”等等)。

    【讨论】:

    • 太好了,现在可以明白他们的意思了。我只是在考虑我的规则和项目交互的方式,以及是否可以改进,但也许那是另一个问题。无论如何,此刻,我遍历 PromotionalRules 对象中的规则对象数组,并将它们相应地应用于每个项目
    • @namtax:根据规则,将整个项目列表交给规则集并让规则集循环遍历项目可能会更好,这样会更容易处理“2 for 1" 的价格之类的。
    • 是的。尽管这将涉及嵌套循环,就像循环规则一样,然后循环该循环中的项目。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-06
    • 2013-01-06
    • 1970-01-01
    • 2019-11-02
    • 2014-04-17
    • 1970-01-01
    相关资源
    最近更新 更多