Каков предпочтительный способ (лучший стиль) для именования пространства имен в Ruby?Единственное или множественное число? - PullRequest
26 голосов
/ 15 февраля 2012

Каковы ваши плюсы и минусы использования:

FooLib::Plugins
FooLib::Plugins::Bar

против

FooLib::Plugin
FooLib::Plugin::Bar

соглашений об именах?И что бы вы использовали или что вы используете?Что чаще всего используется в сообществе?

Ответы [ 5 ]

20 голосов
/ 12 октября 2012

Использование:

module FooLib end
module FooLib::Plugins end
class  FooLib::Plugins::Plugin; end #the base for plugins
class  FooLib::Plugins::Bar < FooLib::Plugins::Plugin; end
class  FooLib::Plugins::Bar2 < FooLib::Plugins::Plugin; end

или другими словами:

module FooLib
  module Plugins
    class Plugin; end #the base for plugins
    class Bar < Plugin; end
    class Bar2 < Plugin; end
  end
end

Также расположите файлы следующим образом:

- foo_lib/
  - plugins/
    - plugin.rb
    - bar.rb
    - bar2.rb

Это как это делает Rails (так что это путь Rails).Т.е. посмотрите на пространство имен Ассоциаций и Ассоциации :: Класс ассоциаций , от которого все классы образуют пространство имен Ассоциаций (т.е. Ассоциации :: SingularAssociation ).

13 голосов
/ 15 февраля 2012

Для меня FooLib::Plugins выглядит как модуль, используемый как пространство имен, в котором хранятся различные классы плагинов. FooLib::Plugin выглядит как суперкласс для плагинов FooLib.

В FooLib::Plugins::Bar, Barопределенно похоже на название плагина.С FooLib::Plugin::Bar я бы сомневался, был ли Bar вспомогательным классом, используемым Foo::Plugin, или именем плагина.

4 голосов
/ 15 февраля 2012

Предполагается, что Plugin является базовым классом:

  • class FooLib::Plugin::Bar < FooLib::Plugin

    Это тот, который я использую и рекомендую.Bar - это Plugin в FooLib и , которое наследуется от FooLib::Plugin.Он также содержит плагины, предоставляемые библиотекой FooLib, вложенной в пространство имен общего класса, которое выглядит естественно:

    # Assign the Bar Plugin of the FooLib library to p.
    p = FooLib::Plugin::Bar
    

    Если бы я разработал сторонний плагин для вашей библиотеки, я бы создалследующая структура:

    # Baz is a Plugin for the FooLib library provided by BarLib.
    class BarLib::FooLib::Plugin::Baz < ::FooLib::Plugin
    

    Обратите внимание, что я отражаю иерархию FooLib, но в пространстве имен BarLib.Я бы не стал расширять его напрямую.

  • class FooLib::Plugins::Bar < FooLib::Plugin

    Я также использовал это, и я думаю, что это имеет смысл.Bar расширяет FooLib::Plugin и является одним из Plugins, предоставленных FooLib.Однако он создает потенциально ненужный модуль.

    Я думаю, это был бы отличный выбор, если бы Plugins был центральным хранилищем плагинов, который реализует такие методы, как Plugins.add, Plugins.all и Plugins.loaded.

    Используйте его, если можете оправдать дополнительный модуль.

  • class FooLib::Plugins::Bar < FooLib::Plugins

    Не имеет большого смысла для меня.Bar является одним из Plugins в FooLib, эта часть выглядит хорошо.Тем не менее, он наследует от Plugins.Это наследование от более чем одного плагина?Это звучит странно для меня;имя класса не должно указывать на то, что невозможно.

2 голосов
/ 05 ноября 2013

Я бы поддержал подход, изложенный @jtrim.

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

module Foo
  module Plugin

    def self.included(base)
      raise "cannot be included"
    end

    def self.extended(base)
      raise "cannot extend"
    end

    def self.new(*args)
      Base.new(*args)
    end

    class Base;end
  end
end


base_plugin_obj = Foo::Plugin.new(...)
1 голос
/ 01 июня 2012

Как правило, я склоняюсь к следующему подходу:

module Foo
  module Plugin
    class Base; end
  end
end

class Foo::Plugin::Bar < Foo::Plugin::Base; end

Класс Base для плагинов - это соглашение, встречающееся повсеместно в кодовой базе RubyOnRails, а также во многих других.(например, ActiveRecord::Base, ActionController::Base и т. д.)

Я не согласен с подходом @Matheus Moreira, где Foo::Plugin используется как базовый класс и пространство имен для плагинов.

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

...