Правильно инкапсулировать коллекцию массивов - PullRequest
1 голос
/ 04 ноября 2011

Привет, мне было поручено создать приложение со следующим заданием.

Внедрить интерфейс, который рассчитывает цены на основе промо-правил.

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

По сути, в зависимости от установленных промо-правил, определенные предметы соответственно обесцениваются.

У меня была некоторая обратная связь с моим кодом, в которой говорилось, что я инкапсулировал группу promo_rules, а затем все равно выставил правила в виде массива - плохо ОО

Я изначально создал объект promo_rules, который содержит массив правил.

  def initialize
    @rules = []
  end

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

Тогда в моем объекте оформления заказа у меня есть объект promo_rules, который был настроен и передан в инициализатор. Я перебираю массив правил, содержащихся в объекте promo_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

Я не слишком доволен своим кодом ... цикл с циклом и т. Д. Но я просто ищу некоторую помощь с инкапсуляцией, так как я не уверен, где я ошибся.

Любые предложения о хороших шаблонах проектирования, которые будут применяться к брифу, также будут полезны, так как не слишком уверены в подходе, который я выбрал. Спасибо

1 Ответ

2 голосов
/ 04 ноября 2011

Я предполагаю, что они жалуются на это "разоблачение":

for rule in @promotionalrules.getrules

, которое выводит внутренние правила из ваших Promotionalrules (которые, вероятно, должны называться 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) }

Существенным изменением является то, что вы применяете набор правил в целом к ​​каждому элементу.Это скрывает детали реализации набора правил и, в качестве дополнительного бонуса, позволяет легко поддерживать правила, которые зависят друг от друга («вы можете получить скидку X, если не используете купон Y» и тому подобное).

...