Подклассы Ruby: Включение различных модулей на основе наследования - PullRequest
2 голосов
/ 02 июля 2010

У меня есть два класса, Задача и Подзадача. Подзадача очень мало отличается от Задачи, за исключением одной важной вещи, она должна включать другой модуль.

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

Например, ниже, вы видите belongs_to в Задаче. belongs_to расширен от включенного модуля, однако его функции немного отличаются в зависимости от того, какой модуль я включаю.

class Subtask < Task
  include subtask_module 
end

class Task
  include task_module

  # methods and aliases both classes use (defined in included file) 
  # but behavior changes based on
  # included file
  belongs_to :template    
end

Какой лучший способ сделать что-то подобное? Прямо сейчас это работает как сейчас. Но это кажется раздутым, потому что в Задаче будут объявлены неиспользованные вещи, которые мне не нужны.

Какой самый лучший способ?

1 Ответ

4 голосов
/ 02 июля 2010

Вы можете также превратить Задачу в подкласс, а затем каждый из них наследовать от чего-то общего (используя ваши имена сверху, где это возможно)

class Task
  belongs_to :template    
end

class Subtask1 < Task
  include subtask_file 
end

# this used to be Task, now is Subtask2
class Subtask2 < Task
  include task_file
end

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

module TaskShared
  belongs_to :template    
end

class Task
  include TaskShared
  include task_file
end

class Subtask
  include TaskShared
  include subtask_file 
end

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

module TaskShared
  def self.included(klass)
    klass.belongs_to :template
  end
end

Обратите внимание, что в некоторых случаях это становится неэффективным, например, наследование от ActiveRecord :: Base классов.

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