初始化Ruby类的习惯方式

问题描述:

初始化Person对象的习惯用法是什么?我个人更喜欢person2,但我是Ruby的新手。初始化Ruby类的习惯方式

class Person 
    attr_reader :first, :middle, :last, :phone_number 

    def initialize(first, middle, last, phone_number) 
     @first = first 
     @middle = middle 
     @last = last 
     @phone_number = phone_number 
    end 
end 

if caller.length == 0 
    person1 = Person.new("John", "T", "Smith", "555-5555") 
    person2 = Person.new(
     first=  "John", 
     middle=  "T", 
     last=  "Smith", 
     phone_number="555-5555", 
    ) 
end 

通常在Ruby中,创建对象要么喜欢person1或用以下方式:

class Person 
    attr_reader :first, :middle, :last, :phone_number 

    def initialize(options) 
     @first = options[:first] 
     @middle = options[:middle] 
     @last = options[:last] 
     @phone_number = options[:phone_number] 
    end 
end 

person = Person.new(first: "John", middle: "T", last: "Smith", phone_number"555-5555") 

有关此替代方法的好处是,你可以选择包括尽可能多或尽可能少的属性为你喜欢,以及允许任意排序。

+0

感谢您的回复。我在'def __init __(self,** kwargs)'中看到了类似Python的东西。我个人认为,这使得初始化程序非常难以阅读。 'options'或'** kwargs'没有告诉我传递给初始值设定项的任何信息,所以我必须深入了解实现逻辑以了解如何正确初始化对象。我想现在我会坚持用'person1'的例子:) – Ben

person1 = Person.new("John", "T", "Smith", "555-5555") 

在我看来是一个更好的选择。会有一些人会不同意,但这就是我为什么这么想的原因。

首先,你应该写你的代码尽可能的可读。这样,人们就不必多问几个问题就能明白为什么要按照它的方式编写/构建。所以,如果你以第二种方式来做,你会解释。但是,通过这样做的第二种方式,就像承认人们阅读您的代码时所写的那样,它的写法并不像第一次那样好。任何软件开发人员都会知道他们可以查看构造函数的参数名称,或者您的IDE已经使用自动文档的形式进行了指定。这两个符号的另一种上面会在构造函数初始化的人的名字如下

person1 = Person.new("John Smith") 

,甚至更好...

person1 = Person.new() 

,然后将字段作为必要解释一下什么设置正在发生。

person1.address = "Blah street" 
person1.phoneNumber = "555-5555" 

现在,虽然我完全理解为什么第二个可能看起来更好,但从长远来看,它会受到伤害。代码中不必要的绒毛,通过精简的设计和强大的工具可以更好地去除。

+0

感谢您的回复。如果我明确设置字段(即'person1.address =“blah”'),那么我将不得不将'attr_reader'的'address'字段更改为'attr_accessor'。再说一遍,我是Ruby的新手,但对于访问控制尽可能限制性地使用它是否有意义? – Ben

+1

说实话,我不是主要的Ruby开发人员。我花了大约2年的时间与Ruby,但主要在C#工作,所以我的建议应该与一粒盐。当涉及到尽可能的限制时,它取决于你计划如何在生命周期中使用对象。如果它应该作为一种常数并在系统的各个部分之间传递,那么是的,我会坚持使用构造函数初始化或针对您的环境更详细的说明。否则,你需要暴露一些可以工作的形式的setter。最好的情况下,你可以使用工厂。 – cmw2379