Каковы для вас плюсы и минусы использования:
FooLib::Plugins
FooLib::Plugins::Bar
против.
FooLib::Plugin
FooLib::Plugin::Bar
соглашения об именах? И что бы вы использовали или что используете? Что чаще всего используется в сообществе?
Каковы для вас плюсы и минусы использования:
FooLib::Plugins
FooLib::Plugins::Bar
против.
FooLib::Plugin
FooLib::Plugin::Bar
соглашения об именах? И что бы вы использовали или что используете? Что чаще всего используется в сообществе?
Использование:
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).
Мне FooLib::Plugins отображается как модуль, используемый как пространство имен, в котором хранятся различные классы плагинов. FooLib::Plugin выглядит как суперкласс для плагинов FooLib.
В FooLib::Plugins::Bar, Bar определенно похоже на имя плагина. С FooLib::Plugin::Bar я сомневаюсь, что Bar был вспомогательным классом, используемым Foo::Plugin, или именем плагина.
Предполагая, что 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 extends FooLib::Plugin и является одним из Plugins, предоставленным FooLib. Однако он создает потенциально ненужный модуль.
Я думаю, что это был бы отличный выбор, если Plugins был центральным репозитором плагинов, который реализует такие методы, как Plugins.add, Plugins.all и Plugins.loaded.
Используйте его, если вы можете обосновать дополнительный модуль.
class FooLib::Plugins::Bar < FooLib::Plugins
Не имеет большого смысла для меня. Bar является одним из Plugins в FooLib, эта часть выглядит отлично. Однако он наследует от Plugins. Наследует ли он от нескольких плагинов? Это звучит странно для меня; имя класса не должно предлагать что-то невозможное.
Как правило, подход, который я предпочитаю, имеет следующий вид:
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 можно найти гораздо меньше экземпляров классов как пространств имен, чем модулей. Единственный раз, когда я действительно вижу классы, используемые как пространство имен для другого класса, заключается в том, что цель этого класса является частной для класса пространства имен и не используется извне.
Я бы включил подход, описанный @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(...)