2012-03-28 74 views
2

正如你可以看到下面的类声明2私有实例变量和2得到& 2设置方法与每个私人成员关联,以允许对它们进行操作和验证。良好的软件实践 - 获取和设置方法

我的问题是:哪个更适合在构造函数的减速中使用,实例变量直接如下面的代码片段所示,或者使用与它们相关联的set方法,以及哪些是在toString中使用的良好软件实践方法,实例变量或他们的getter方法?

谢谢你的时间。

public Class Employee { 

    private String firstName; 
    private String lastName; 

    public Employee (String first, String last) 
    { 
    firstName = first; 
    lastName = last; 
    }//end of constructor 

    public void setFirstName(String first) 
    { 
    firstName = first; 
    }//end of method setFirstName 

    public String getFirstName() 
    { 
    return firstName; 
    } 

    public void setLastName(String last) 
    { 
    lastName = last; 
    }//end of method setLastName 

    public String getLastName() 
    { 
    return lastName; 
    }//end of method getLastName 

    public String toString() 
    { 
    return String.format ("%s: %s %s\n", "Employee Name: ", firstName, lastName); 
    }//end of method toString 

}//end of class Employee 

回答

5

我倾向于通过构建来支持初始化。通过使用此方法并提供适当的检查(编译时间通过final和运行时通过空检查或类似),您可以确保您的对象正确并且完全实例化。

在字段上使用final关键字将使编译器检查您在构建时是否为该字段赋值。这确实意味着该领域是不可改变的,但令人惊讶的是你需要多久。

我会小心提供一切的getter。如果你不断提供和使用getter,那就表明你正在从对象中提取数据并在该对象之外操纵它。记住 - 面向对象的一个​​关键原则是让对象为你做事,而不是要求他们自己做数据。

+1

除此之外,作为一个经验法则,在构造函数中使用可重写的方法是不鼓励的,因为它使代码完全无法维护(至少在我遇到过的情况下)。 – fjdumont 2012-03-28 14:59:09

+0

谢谢布赖恩的时间和解释。这是有帮助的。 – Sinan 2012-03-28 15:03:09

1

如果你希望你的类进行扩展(和的getter/setter覆盖),最好是使用的方法,而不是变量。

注意:我不确定在构造函数中发生了什么,您可能更适合直接设置变量。

您可以将getter/setter标记为final,然后您不必担心覆盖。仍然是一个很好的做法,使用这些方法,而不是直接访问,因为您可以更容易地在那里放置断点或调试语句

+0

谢谢Attila的回答!可能会向您提出另一个问题 - 就字符串验证而言 - 您从中体验到了什么是您在验证代码中验证字符串的过程中所要做的事情!再次感谢你。 – Sinan 2012-03-28 14:58:04

+0

你想要验证什么?顺便说一句,你可能会更好地发布这个作为一个新的问题,更精细的解释你想要实现什么 – Attila 2012-03-28 15:10:16

+0

谢谢我今天晚些时候可以做到这一点! – Sinan 2012-03-28 15:14:13

2

规则1,总是限制访问所需最低限度的,即除非你明确需要修改第一/姓氏的值,使对象不可变的(构造函数的参数,没有制定者只干将)

+0

好的规则,但我会说这是除了在这种情况下的点。 – claesv 2012-03-28 15:00:35

0

我会使用setter。有时你在setters中有额外的代码。例如,列表的setter可能会挂钩列表的Changed事件,并且通过不使用setter,您将不会捕获Changed事件。

1

一般来说,我倾向于避免从构造函数中调用非静态方法(因为对象在该阶段未完全初始化)。如果setter方法只将字段设置为参数值,就像上面那样,我只是将它设置在构造函数中(即不调用setter)。如果setter更复杂,我会尝试将逻辑分解为静态辅助方法,并从构造函数和setter方法中使用它。例如:

int field_;  

Constructor(int initialValue) { 
    field_ = helper(initialValue); 
} 

public void setField(int value) { 
    field_ = helper(value); 
} 

// not really complex, but avoid duplication of logic 
private static int helper(int value) { 
    return 2*value; 
} 
+0

谢谢Claesv。 – Sinan 2012-03-28 15:05:11