坏味道——纯稚的数据类(Data Class)
特征
纯稚的数据类(Data Class)
指的是只包含字段和访问它们的getter和setter函数的类。这些仅仅是供其他类使用的数据容器。这些类不包含任何附加功能,并且不能对自己拥有的数据进行独立操作。
问题原因
当一个新创建的类只包含几个公共字段(甚至可能几个getters / setters)是很正常的。但是对象的真正力量在于它们可以包含作用于数据的行为类型或操作。
解决方法
- 如果一个类有公共字段,你应该运用
封装字段(Encapsulated Field)
来隐藏字段的直接访问方式。 - 如果这些类含容器类的字段,你应该检查它们是不是得到了恰当的封装;如果没有,就运用
封装集合(Encapsulated Collection)
把它们封装起来。 - 找出这些getter/setter函数被其他类运用的地点。尝试以
搬移函数(Move Method)
把那些调用行为搬移到纯稚的数据类(Data Class)
来。如果无法搬移这个函数,就运用提炼函数(Extract Method)
产生一个可搬移的函数。
- 在类已经充满了深思熟虑的函数之后,你可能想要摆脱旧的数据访问方法,以提供适应面较广的类数据访问接口。为此,可以运用
移除设置函数(Remove Setting Method)
和隐藏函数(Hide Method)
。
收益
- 提高代码的可读性和组织性。特定数据的操作现在被集中在一个地方,而不是在分散在代码各处。
- 帮助你发现客户端代码的重复处。
重构方法说明
封装字段(Encapsulated Field)
问题
你的类中存在public字段。
class Person {
public String name;
}
解决
将它声明为private,并提供相应的访问函数。
class Person {
private String name;
public String getName() {
return name;
}
public void setName(String arg) {
name = arg;
}
}
封装集合(Encapsulated Collection)
问题
有个函数返回一个集合。
解决
让该函数返回该集合的一个只读副本,并在这个类中提供添加、移除集合元素的函数。
搬移函数(Move Method)
问题
你的程序中,有个函数与其所驻类之外的另一个类进行更多交流:调用后者,或被后者调用。
解决
在该函数最常引用的类中建立一个有着类似行为的新函数。将旧函数变成一个单纯的委托函数,或是旧函数完全移除。
提炼函数(Extract Method)
问题
你有一段代码可以组织在一起。
void printOwing() {
printBanner();
//print details
System.out.println("name: " + name);
System.out.println("amount: " + getOutstanding());
}
解决
移动这段代码到一个新的函数中,使用函数的调用来替代老代码。
void printOwing() {
printBanner();
printDetails(getOutstanding());
}
void printDetails(double outstanding) {
System.out.println("name: " + name);
System.out.println("amount: " + outstanding);
}
移除设置函数(Remove Setting Method)
问题
类中的某个字段应该在对象创建时被设值,然后就不再改变。
解决
去掉该字段的所有设值函数。
隐藏函数(Hide Method)
问题
有一个函数,从来没有被其他任何类用到。
解决
将这个函数修改为private。
引申阅读
欢迎继续阅读 代码的症与药 系列文章。