【问题标题】:Are modules in ruby only meant to be used when multiple objects require its functionality?ruby 中的模块是否仅在多个对象需要其功能时才使用?
【发布时间】:2011-03-24 16:18:41
【问题描述】:

我读过一个模块提供的主要服务是包含和分组多个对象所需的类似功能。但是,即使您确定只有一个对象需要它的服务,也为解析器之类的东西创建一个模块是一种好习惯吗?

【问题讨论】:

  • 你怎么能确定只有一个对象(我怀疑你想的是 class 代替)会对使用该模块感兴趣?如果这些方法与单个类有如此多的耦合,那么它们应该是类本身的成员听起来更合乎逻辑。

标签: ruby-on-rails ruby oop


【解决方案1】:

模块有两个用途。正如您所注意到的,第一个是允许将功能添加到一组不同的类(继承树之外的不同含义)。第二个更常见的用途是组织名称空间。当您看到像 ActiveRecord::BaseBSON::ObjectID 这样的代码时,这些 gem 的作者已将它们的功能分别放在一个模块中,ActiveRecordBSON,以防止它们的类名与它们所包含的应用程序或其他应用程序发生冲突图书馆。

使用您提到的解析器,在我看来您想要构建一个单例类而不是一个模块。

【讨论】:

    【解决方案2】:

    即使您在一个地方使用它,它也可以帮助组织创建一个模块。例如,您可能有很多方法都相关,但与您包含模块的代码并不真正相关。这类似于类提供的组织,除了模块不专注于对象。

    【讨论】:

      【解决方案3】:

      模块提供的主要服务是 包含和分组类似的功能 多个对象所需要的

      我将把它改写为“将可能至少一个对象需要的类似功能分组”。您经常不知道最终将包含或扩展一个模块的类有多少(例如,如果您正在编写一个库)

      除此之外,我还看到了另外两个“主要目的”:

      • 它们是提供范围的一种方式(您可以将多个类和其他模块打包到一个模块中)。
      • 他们有一个名为included 的回调。这可能看起来微不足道,但回调是许多有趣的元编程技术的关键。

      【讨论】:

      • +1 仅仅因为您目前只有一个用途并不意味着您将来不想重复使用它。
      【解决方案4】:

      我会去上课(如果你没有太多代码的话)。放在/lib下

      class Parse
        def self.xml(xml_string)
          ...
        end
      end
      
      Parse.xml("<xml></xml>")
      
      1. 您可以从任何地方调用它。
      2. http://en.wikipedia.org/wiki/Separation_of_concerns

      模块确实是一组类似的功能。如果你有很多解析代码,你可以这样做:

      class Xml
        acts_as_parser
      end
      
      class Json
        acts_as_parser
      end
      
      ...
      

      acts_as_parser 将从模块中加载函数组。

      【讨论】:

        【解决方案5】:

        但是,即使您确定只有一个对象需要它的服务,也为解析器之类的东西创建一个模块是一种好习惯吗?

        是的。

        在 Ruby 中,模块在分离关注点方面有很大帮助,并且非常适合进行“面向方面”的编程(即,使用 mixins 很有趣)。

        # Basic Hierarchy
        class X
          def say ; 'X' end
        end
        class Y < X
          def say ; super + 'Y' end
        end
        y = Y.new
        y.say #=> 'XY'
        
        # Throwing in an aspects/mixins
        module A
          def say ; super + 'A' end
        end
        class Y
          include A
        end
        y.say #=> 'XAY'
        
        # Throwing in another aspects/mixins
        module B
          def say ; super + 'B' end
        end
        class Y
          include B
        end
        y.say #=> 'XABY'
        

        【讨论】:

          【解决方案6】:

          当面对一个过大的类时,有时我会根据它的功能将它分成几个模块,并让一个几乎空的类只包含这些模块。

          【讨论】:

            猜你喜欢
            • 2017-11-06
            • 1970-01-01
            • 1970-01-01
            • 2012-05-15
            • 2017-11-09
            • 1970-01-01
            • 2012-11-10
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多