我有一个私人领域的课程:
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
实现更好,即使它打破了封装?
答案 0 :(得分:1)
我认为根本没有设置名称的方法,它应该是一个构造函数参数:
Person somePerson(view.askUserForName());
您的方法的问题是您首先创建未完全初始化的对象,因此使用起来很危险:Person somePerson
。如果忘记setName
怎么办?你的代码是否仍然适用于这个"空"人
然后你允许用setName
方法直接修改内部状态,这也不好。
使用构造函数参数可以避免这两个问题。
至于原来的问题 - 我不认为这两种方法有很大的不同。
结果完全相同 - 您调用方法并更改内部对象状态。您可以将其命名为setName
或changeName
,结果相同。
changeName(view)
的第二种方法实际上更糟糕,因为您还引入了Person
对View
对象的依赖关系。
现在,如果要更改名称,则始终需要首先创建View
对象。