рубиновый вопрос - PullRequest
       6

рубиновый вопрос

2 голосов
/ 18 января 2011

Извините за хромое название: я не знаю, как подвести итог этого ...

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

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

В моей системе пользователи могут настроить, какой класс формул использовать, и действительно могут рассчитывать, используя, например, несколько формул для сравнительного отчета.

Я пытаюсь выяснить, как передать значения атрибута между внутренним классом / формулой и внешним / персистентным классом без строки за строкой inner.x = outer.x кода.

Мне кажется, я не могу использовать:

class Outer
   include Formula1
end

... потому что я хочу, чтобы фактический класс Formula был настраиваемым.

Одна идея, которая приходит на ум, заключается в том, что я мог бы иметь массив атрибутов для передачи из моего внешнего класса и циклически перебирать их и send, примерно так:

# not tested
['x', 'y', 'z'].each{|a|@formula.send("#{a.to_sym}=", self.send("#{a.to_sym}") }

Любая другая рубиновая магия или шаблоны, которые я должен рассмотреть?

Спасибо

Ответы [ 2 ]

0 голосов
/ 18 января 2011

Похоже, вы ищете шаблон Стратегии для подключения формулы, а затем, возможно, Фасад, если вы не хотите вызывать атрибут формулы через экземпляр формулы.

Простой способ создать стратегию - сделать экземпляр формулы одним из атрибутов Внешнего:

class Outer

  attr_accessor :formula #this bit is Strategy

  def x #this bit is Facade
    @formula.x
  end

  def calculate #Facade
    @formula.calculate
  end

end

outer1 = Outer.new

outer1.formula = Formula17.new

#this is the same
outer1.formula.x = 2
outer1.x = 2

#these are the same
puts outer1.formula.x
puts outer1.x

#and these are the same
puts outer1.formula.calculate
puts outer1.calculate

#and this would be the same as the above
formula17 = Formula17.new
formula17.x = 2
outer1 = Outer.new
outer1.formula = formula17

Чтобы справиться с множеством методов доступа, возможно, вы могли бы попробовать метод, отсутствующий, либо вызвать, либо определить и вызвать методы для вас так, как они вызваны?

def method_missing(meth, *args, &block)
  if @formula.respond_to?(meth)
    @formula.send(meth, *args, &block)
  end
  else
    super(meth, *args, &block)
  end
end
0 голосов
/ 18 января 2011

Мой ruby-fu низкий, и мне, вероятно, не хватает тонкости вашего требования, так что это, вероятно, не лучший вариант, но у вас может быть модуль, для которого вы определяете атрибуты, а затем включаете этот модуль в свой Outer и Классы формул, как это:

module FormulaAttributes
  attr_accessor :x, :y ...
end

class Formula1
  include FormulaAttributes
end

class Outer1
  include FormulaAttributes
  attr_accessor :a, :b ...
end
...