Подтвердить что ты не робот

Когда использовать модуль и когда использовать класс

В настоящее время я работаю над книгой Gregory Brown Ruby Best Practices. В начале он говорит о реорганизации некоторых функций из вспомогательных методов в связанном классе, с некоторыми методами на модуле, а затем имеет модуль extend self.

Не видел, что раньше, после быстрого google, выяснилось, что extend self в модуле позволяет методам, определенным в модуле, видеть друг друга, что имеет смысл.

Теперь, мой вопрос: когда бы вы сделали что-то вроде этого

module StyleParser
  extend self

  def process(text)
    ...
  end

  def style_tag?(text)
    ...
  end
end

а затем обратитесь к нему в тесте

@parser = Prawn::Document::Text::StyleParser

в отличие от чего-то подобного?

class StyleParser

  def self.process(text)
    ...
  end

  def self.style_tag?(text)
    ...
  end
end 

Это так, что вы можете использовать его как mixin? или есть другие причины, которые я не вижу?

4b9b3361

Ответ 1

Класс должен использоваться для функциональности, которая потребует создания экземпляра или для отслеживания состояния. Модуль может использоваться как способ сочетания функциональности с несколькими классами или как способ предоставления одноразовых функций, которые не нужно создавать или отслеживать состояние. Метод класса также может быть использован для последнего.

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

Ответ 2

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

Класс - это factory для объектов (обратите внимание на множественное число). Если вы не хотите создавать несколько экземпляров класса, нет необходимости в его существовании.

Модуль представляет собой контейнер для методов, разделяемых между несколькими объектами. Если вы не смешиваете модуль в нескольких объектах, нет необходимости в его существовании.

В этом случае похоже, что вы просто хотите объект. Поэтому используйте один:

def (StyleParser = Object.new).process(text)
  ...
end

def StyleParser.style_tag?(text)
  ...
end

Или, альтернативно:

class << (StyleParser = Object.new)
  def process(text)
    ...
  end

  def style_tag?(text)
    ...
  end
end

Но поскольку @Azeem уже писал: для правильного решения вам нужен больше контекста. Я недостаточно хорошо знаком с внутренними силами Кревеца, чтобы узнать, почему Грегори принял это конкретное решение.

Ответ 3

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