代码之家  ›  专栏  ›  技术社区  ›  Matt Briggs

何时使用模块,何时使用类

  •  20
  • Matt Briggs  · 技术社区  · 14 年前

    我现在在格雷戈里·布朗那边工作 Ruby Best Practices 书。早期,他正在讨论重构一些功能,从相关类上的helper方法到模块上的一些方法,然后让模块 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 
    

    这样你就可以把它当作调味品了吗?或者还有其他原因我没看到?

    3 回复  |  直到 14 年前
        1
  •  37
  •   Jimmy Nitzan Tomer    14 年前

    类应该用于需要实例化或需要跟踪状态的功能。模块既可以用作将功能混合到多个类中的方法,也可以用作提供不需要实例化或跟踪状态的一次性功能的方法。类方法也可以用于后者。

    有鉴于此,我认为区别在于你是否真的需要一门课。当现有类需要一些单例功能时,类方法似乎更合适。如果您所做的只是由单例方法组成,那么将其实现为一个模块并直接通过该模块访问就更有意义了。

        2
  •  7
  •   Jörg W Mittag    14 年前

    在这种情况下,我可能既不使用类也不使用模块。

    类是对象的工厂(注意复数)。如果不想创建类的多个实例,则不需要该类存在。

    模块是方法的容器,在多个对象之间共享。如果不将模块混合到多个对象中,则不需要它存在。

    在这种情况下,看起来你只是想要一个对象。所以使用一个:

    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
  •  -1
  •   Azeem.Butt    14 年前

    如果要实例化某个对象,请使用类。你剩下的问题需要更多的上下文才能理解。