主页 > 知识库 > 网络编程 > Ruby >

Ruby 编程风格介绍(4)

来源:ruby-china 作者:网络 发表于:2012-06-20 09:50  点击:
而不是 find_all 是因为 select 与 reject 一同使用时很不错, 并且它的名字具有很好的自解释性。 注释 Good code is its own best documentation. As youre about to add a comment, ask yourself, How can I impr
而不是find_all是因为selectreject一同使用时很不错,
并且它的名字具有很好的自解释性。

注释

Good code is its own best documentation. As you're about to add a
comment, ask yourself, "How can I improve the code so that this
comment isn't needed?" Improve the code and then document it to make
it even clearer.
-- Steve McConnell
  • 写出可以“自解释”的代码,然后忽略后面的内容,这不是在开玩笑!
  • Comments longer than a word are capitalized and use punctuation. Use one space after periods.
  • 避免无意义的注释。
    # 不好的
    counter += 1 # increments counter by one
    
  • 时常更新现有的注释。没有注释优于过时的注释。
  • 不要为糟糕的代码写注释。重构它们,使它们能够“自解释”。(Do or do not - there is no try.)

注解

  • 代码的注解应该总是写在被注释代码的上面, 并且紧贴被注释代码.
  • 注解的标题应该紧跟一个冒号以及一个空格, 用来突出显示该注释描述的内容.
  • 如果需要多行注释, 第二行注释应该在#之后缩进两个空格.(译者注: 以上两条规则在Ruby源码中都不多看到, 前者在Lisp源码较多见, 而后者从没见过)
    def bar
      # FIXME: This has crashed occasionally since v3.2.1. It may
      # be related to the BarBazUtil upgrade.
      baz(:quux)
    end
    
  • 如果代码很直白, 添加注解就显得多余, 也可以在代码所在行的尾部提供简短的注解说明.不过这应该在很少的情况下使用, 并且不被提倡.
def bar
  sleep 100 # OPTIMIZE
end
  • 使用TODO标题描述 漏掉的功能或打算加入的新特性
  • 使用FIXME标题描述 需要被修复的有问题代码
  • 使用OPTIMIZE标题描述 可能有性能瓶颈, 需要优化的代码.
  • 使用HACK标题描述 感觉上需要重构的代码
  • 使用REVIEW标题描述 关键性代码, 需要稍后不断的检查该代码是否工作正确.
  • 只要对阅读代码有帮助, 也可以使用其他直白的注解标题, 但记得在README中注明.

类相关

  • 当设计一个类时, 务必记住LSP原则.(译者注: LSP原则大概含义为: 如果一个函数中引用了`父类的实例', 则一定可以使用其子类的实例替代, 并且函数的基本功能不变. (虽然功能允许被扩展)
  • 尽量使你的类更加健壮, 稳固.
  • 为你自己的类定义to_s方法, 用来表现这个类实例对象的字符化表现形式.
    class Person
      attr_reader :first_name, :last_name
    
      def initialize(first_name, last_name)
        @first_name = first_name
        @last_name = last_name
      end
    
      def to_s
        "#@first_name #@last_name"
      end
    end
    
  • 尽量使用attr来定义属性访问器或修改器方法.
    # bad
    class Person
      def initialize(first_name, last_name)
        @first_name = first_name
        @last_name = last_name
      end
    
      def first_name
        @first_name
      end
    
      def last_name
        @last_name
      end
    end
    
    # good
    class Person
      attr_reader :first_name, :last_name
    
      def initialize(first_name, last_name)
        @first_name = first_name
        @last_name = last_name
      end
    end
    
  • 考虑添加工厂方法, 用以灵活的创建一个特定类的实例.
    class Person
      def self.create(options_hash)
        # body omitted
      end
    end
    
  • Ruby的基本价值观之一: duck-typing优先于继承.
    # bad
    class Animal
      # abstract method
      def speak
      end
    end
    
    # extend superclass
    class Duck < Animal
      def speak
        puts 'Quack! Quack'
      end
    end
    
    # extend superclass
    class Dog < Animal
      def speak
        puts 'Bau! Bau!'
      end
    end
    
    # good
    class Duck
      def speak
        puts 'Quack! Quack'
      end
    end
    
    class Dog
      def speak
        puts 'Bau! Bau!'
      end
    end
    
  • 应该总是避免使用类变量.
    class Parent
      @@class_var = 'parent'
    
      def self.print_class_var
        puts @@class_var
      end
    end
    
    class Child < Parent
      @@class_var = 'child'
    end
    
    Parent.print_class_var # => will print "child"
    
    正如上例看到的, 所有的类实例共享类变量, 并且可以直接修改类变量,此时使用类实例变量是更好的主意.
  • 总是为类的实例方法定义适当的可见性.(private, protected, private), 不应该总是使用public (默认可见性为public), 这不是Python!
  • 可见性关键字应该和方法定义有相同的缩进, 并且不同的关键字之间要空行分隔.
    class SomeClass
      def public_method
        # ...
      end
    
      private
      def private_method
        # ...
      end
    end
    
  • 总是使用self来定义单例方法. 当代码重构时, 这将使得方法定义代码更加具有灵活性.
    class TestClass
      # bad
      def TestClass.some_method
        # body omitted
      end
    
      # good
      def self.some_other_method
        # body omitted
      end
    
      # Also possible and convenient when you
      # have to define many singleton methods.
      class << self
        def first_method
          # body omitted
        end
    
        def second_method_etc
          # body omitted
        end
      end
    end
    
                

有帮助
(0)
0%
没帮助
(0)
0%