避免使用setter来改变class的属性值

时间:2016-02-22 12:25:03

标签: oop encapsulation setter getter-setter

我有一个私人领域的课程:

class Person {
  string name;
  public void setName(string name);
}

然后,使用一些负责与用户交互的对象(在本例中为命令行),我想改变这个字段的值:

Person somePerson;
CommandLineView view;
somePerson.setName(view.askUserForName());

有效。但我不喜欢使用set函数,因为它暴露了类成员。 因此我开始寻找如何避免它。

新实现如下所示:

class Person
{
  string name;
  public void changeName(view) { name = view.askUserForName(); }
}

Person somePerson;
CommandLineView view;
somePerson.changeName(view);

现在Person不公开其成员。此外,该类负责与更改名称相关的逻辑(例如,函数changeName也可以更新数据库,通知感兴趣的各方等。

问题是:这种重构是一种好的做法吗?或者使用setter实现更好,即使它打破了封装?

1 个答案:

答案 0 :(得分:1)

我认为根本没有设置名称的方法,它应该是一个构造函数参数:

Person somePerson(view.askUserForName());

您的方法的问题是您首先创建未完全初始化的对象,因此使用起来很危险:Person somePerson。如果忘记setName怎么办?你的代码是否仍然适用于这个"空"人

然后你允许用setName方法直接修改内部状态,这也不好。

使用构造函数参数可以避免这两个问题。

至于原来的问题 - 我不认为这两种方法有很大的不同。 结果完全相同 - 您调用方法并更改内部对象状态。您可以将其命名为setNamechangeName,结果相同。

changeName(view)的第二种方法实际上更糟糕,因为您还引入了PersonView对象的依赖关系。 现在,如果要更改名称,则始终需要首先创建View对象。