相信任何一个使用过java语言进行企业级应用开发的人都对数据对象很熟悉,dto/vo。
我们经常会需要知道这些数据对象中某些变量的值。如何实现呢?其实很简单。
例如,一个value object定义如下:
我们可以使用System.out.println(new AnnoyingVo().getFirstName());
当然,可以让AnnoyingVo重载Object类的toString方法,以打印其变量值。
import java.io.Serializable;
/**
* An example of value object regarded as a bad design.
* @author Jack 2012-4-22
*/
public class AnnoyingVo extends AbstractVo implements Serializable{
private static final long serialVersionUID = -2668373925215719210L;
private String firstName = null;
private String lastName = null;
private Integer age = null;
private Boolean gender = null;
private String graduatedUniversity = null;
private String interest = null;
private String description = null;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Boolean getGender() {
return gender;
}
public void setGender(Boolean gender) {
this.gender = gender;
}
public String getGraduatedUniversity() {
return graduatedUniversity;
}
public void setGraduatedUniversity(String graduatedUniversity) {
this.graduatedUniversity = graduatedUniversity;
}
public String getInterest() {
return interest;
}
public void setInterest(String interest) {
this.interest = interest;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String toString()
{
return "\nfirstName:" + firstName
+ "\nlastName:" + lastName
+ "\nage:" + age
+ "\ngender:" + gender
+ "\ngraduatedUniversity:" + graduatedUniversity
+ "\ninterest:" + interest
+ "\ndescription" + description;
}
}
这看上去很合理,没有什么值得讨论的地方。
但是如果某个vo类中定义了100个变量。我们要看这100个变量的值,就不得不这样写:
System.out.println(""+""+""+""+""+...);
或者定义一个冗长的toString()方法。
而如果一个系统中有100个这样的vo呢,每个vo被代码引用100次呢?
这种需要不是不会出现。比如,我们希望一段程序出现异常的时候能够记录下来当时vo中所有的信息,以方便进行问题定位。
我以前所在的两个公司都是像上面这样做的。
其实这样做不会有任何问题。但我是一个很怕麻烦的人。我会考虑到一个vo有1000个属性的问题,虽然这种情况不会出现;另一方面,一个合格的程序员应该有对代码进行优化的欲望,我也正向这方面努力。
经过改造的vo类如下,注意,其中不存在toString()方法:
import java.io.Serializable;
public class DelightfulVo extends AbstractVo implements Serializable{
private static final long serialVersionUID = 4250993416351124748L;
private String firstName = null;
private String lastName = null;
private Integer age = null;
private Boolean gender = null;
private String graduatedUniversity = null;
private String interest = null;
private String description = null;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Boolean getGender() {
return gender;
}
public void setGender(Boolean gender) {
this.gender = gender;
}
public String getGraduatedUniversity() {
return graduatedUniversity;
}
public void setGraduatedUniversity(String graduatedUniversity) {
this.graduatedUniversity = graduatedUniversity;
}
public String getInterest() {
return interest;
}
public void setInterest(String interest) {
this.interest = interest;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
toString()方法在抽象基类中定义,通过一些基本的java反射机制获取类成员的值。
import java.lang.reflect.Field;
public abstract class AbstractVo {
public String toString()
{
String s = "";
Class<? extends AbstractVo> cls = getClass();
Field[] fields = cls.getDeclaredFields();
for(Field field : fields)
{
field.setAccessible(true);
try {
if(field.get(this)!=null) {
s += field.getName() + ":" + field.get(this) + "\n";
}
} catch (Exception e) {
return super.toString();
}
field.setAccessible(false);
}
return s;
}
}
附上测试类:
public class Test {
public static void main(String[] argus)
{
Test t = new Test();
t.testAnnoyingVo();
t.testDelightfulVo();
}
public void testAnnoyingVo()
{
AnnoyingVo av = new AnnoyingVo();
av.setFirstName("Jim");
av.setLastName("Green");
av.setAge(new Integer(27));
av.setGender(Boolean.TRUE);
av.setGraduatedUniversity("HarvardUniversity");
av.setDescription(null);
av.setInterest("");
System.out.println(av.toString());
}
public void testDelightfulVo()
{
DelightfulVo av = new DelightfulVo();
av.setFirstName("Jim");
av.setLastName("Green");
av.setAge(new Integer(27));
av.setGender(Boolean.TRUE);
av.setGraduatedUniversity("HarvardUniversity");
av.setDescription(null);
av.setInterest("");
System.out.println(av.toString());
}
}
代码很简单,相信您都能看懂。作用也不大。你不用的话,系统该怎么着,还这么着!
我想说的是,一屋不扫,何以扫天下。