Вопрос в стиле Ruby: блоки или наследование? - PullRequest
4 голосов
/ 14 января 2009

У меня есть несколько классов, которые будут делать что-то, основываясь на некоторых условиях. Условия отправляются в качестве параметров некоторым методам. Мои вопросы связаны со стилем кодирования ruby:

  • должны ли условия быть отправлены как лямбда-выражения или как некоторые объекты, которые наследуются от класса условий?

  • , что более эффективно с точки зрения ООП?

Спасибо!

Ответы [ 4 ]

6 голосов
/ 14 января 2009

Я не знаю, какой из них более эффективен с точки зрения времени выполнения, но блоки более эффективны с точки зрения пользовательского интерфейса. Человек, использующий ваш метод, просто записывает условие в блок вместо того, чтобы определять целый новый класс, создавать экземпляр и передавать его в ваш метод.

4 голосов
/ 14 января 2009

Это все незначительно, и это зависит от того, что вы на самом деле делаете и могут ли кэшироваться объекты условий или процедуры, но в целом блоки - это путь Ruby , и они быстрее, чем создание объекта.

Вот бесполезный тест:

require 'benchmark'

# Useless parent class
class Condition; end

# Useless inheritance.  Duck typing FTW.
class AddCondition < Condition  
  def call
    1 + 1
  end
end

def with_object(condition)
  condition.call
end

def with_block
  yield
end

n = 100000
Benchmark.bm(10) do |x|
  x.report("object:") do
    n.times do; with_object(AddCondition.new); end
  end
  x.report("block:") do
    n.times do; with_block { 1 + 1 };          end
  end
end

И результаты:

                user     system      total        real
object:     0.090000   0.000000   0.090000 (  0.087227)
block:      0.060000   0.000000   0.060000 (  0.063736)
3 голосов
/ 14 января 2009

Лямбды - это больше, чем Ruby - и кроме того, зачем определять целый большой класс для чего-то, что простая лямбда делает просто отлично? В качестве альтернативы вы можете передать условия, как это делает хэш, как это делает Rails.

1 голос
/ 14 января 2009

Единственный случай, в котором я бы использовал наследование в этой ситуации, это если сами условия используют много общего кода, который может быть полностью реализован в суперклассе (без необходимости что-либо переопределять в подпунктах) , но практика использования наследования для интерфейсов в стиле Java не является обычной в Ruby.

В любом случае то, что вы делаете, известно как инверсия шаблонов управления и стратегии, читайте об этом для получения дополнительной информации. Ключом является (хорошее) решение заставить пользователя кода решить, каким будет окончательное поведение вашего кода, в отличие от параметра конфигурации или какого-либо другого рода ветвления в реализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...