Ruby中编写类与模块的风格指南

2019-09-25 09:39:44于海丽

在 class 定义里使用一致的结构。

    

class Person
   # extend and include go first
   extend SomeModule
   include AnotherModule

   # constants are next
   SOME_CONSTANT = 20

   # afterwards we have attribute macros
   attr_reader :name

   # followed by other macros (if any)
   validates :name

   # public class methods are next in line
   def self.some_method
   end

   # followed by public instance methods
   def some_method
   end

   # protected and private methods are grouped near the end
   protected

   def some_protected_method
   end

   private

   def some_private_method
   end
  end

    倾向使用 module,而不是只有类方法的 class。类别应该只在创建实例是合理的时候使用。

   

 # bad
  class SomeClass
   def self.some_method
    # body omitted
   end

   def self.some_other_method
   end
  end

  # good
  module SomeClass
   module_function

   def some_method
    # body omitted
   end

   def some_other_method
   end
  end

    当你希望将模块的实例方法变成 class 方法时,偏爱使用 module_function 胜过 extend self。

 

  # bad
  module Utilities
   extend self

   def parse_something(string)
    # do stuff here
   end

   def other_utility_method(number, string)
    # do some more stuff
   end
  end

  # good
  module Utilities
   module_function

   def parse_something(string)
    # do stuff here
   end

   def other_utility_method(number, string)
    # do some more stuff
   end
  end

    When designing class hierarchies make sure that they conform to the
    Liskov Substitution Principle.

    在设计类层次的时候确保他们符合 Liskov Substitution Principle 原则。(译者注: LSP原则大概含义为: 如果一个函数中引用了 父类的实例, 则一定可以使用其子类的实例替代, 并且函数的基本功能不变. (虽然功能允许被扩展))

        Liskov替换原则:子类型必须能够替换它们的基类型 <br/>
        1. 如果每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都代换为o2时,程序P的行为没有变化,那么类型T2是类型T1的子类型。 <br/>
        2. 换言之,一个软件实体如果使用的是一个基类的话,那么一定适用于其子类,而且它根本不能察觉出基类对象和子类对象的区别。只有衍生类替换基类的同时软件实体的功能没有发生变化,基类才能真正被复用。 <br/>
        3. 里氏代换原则由Barbar Liskov(芭芭拉.里氏)提出,是继承复用的基石。 <br/>
        4. 一个继承是否符合里氏代换原则,可以判断该继承是否合理(是否隐藏有缺陷)。