在Ruby中命名命名空间的首选方式(更好的样式)是什么?单数还是复数?

时间:2012-02-15 12:04:15

标签: ruby module namespaces naming-conventions naming

使用的优点和缺点是什么:

FooLib::Plugins
FooLib::Plugins::Bar

VS

FooLib::Plugin
FooLib::Plugin::Bar

命名约定?你会用什么或者你用的是什么?在社区中更常用的是什么?

5 个答案:

答案 0 :(得分:19)

使用:

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

这是how Rails does it(所以这是Rails方式)。即查看Associations命名空间和Associations::Association class,其中构成Associations命名空间的所有类都继承(即Associations::SingularAssociation)。

答案 1 :(得分:13)

对我而言,FooLib::Plugins看起来像一个模块,用作保存各种插件类的命名空间。FooLib::Plugin看起来像是FooLib插件的超类。

FooLib::Plugins::Bar中,Bar绝对看起来像是插件的名称。使用FooLib::Plugin::Bar,我怀疑BarFoo::Plugin使用的帮助程序类,还是插件的名称。

答案 2 :(得分:4)

假设Plugin是基类:

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

    这是我使用和推荐的那个。 BarPlugin 中的FooLibFooLib::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.addPlugins.allPlugins.loaded等方法的中央插件存储库,这将是一个很好的选择。

    如果可以证明额外模块的合理性,请使用它。

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

    对我来说没有多大意义。 BarPlugins中的FooLib之一,该部分看起来很好。但是,它继承自Plugins。它是从多个插件继承的吗?这听起来很奇怪;班级名称不应该提出不可能的事情。

答案 3 :(得分:2)

我会采用@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(...)

答案 4 :(得分:1)

一般来说,我倾向于采用的方法是:

module Foo
  module Plugin
    class Base; end
  end
end

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

插件的Base类是在RubyOnRails代码库中以及许多其他地方找到的常规。 (例如ActiveRecord::BaseActionController::Base等。)

我不同意@Matheus Moreira的方法,其中Foo::Plugin既用作基类又用作插件的命名空间。

为什么不应该这样做的唯一功能原因与约定有关 - 在Ruby社区中,人们会发现很少的类实例作为名称空间而不是模块。我真正看到用作另一个类的命名空间的类的唯一一次是当所述类的目的是对命名空间类是私有的并且不在外部使用时。