列举下面这段程序10个设计问题(从concise, correctness, clarity, maintainability, optimality角度考虑)(可假设Content, ContentField 类已存在)import java.util.*;public abstract class ContentMap {
private static final int MAX_LENGTH = 65535;
private String data1;
private String data2;
private String data3;
private final int numFields;
public ContentMap(final Content content, final int numFields) {
this.numFields = numFields;
if (content != null) {
for (int i = 1; i <= numFields; i++) {
final ContentField field = content.getField(i);
if (field != null)
setData(i, field.getData());
}
}
} public void displayField(final int dataNum) {
final StringBuffer buf = new StringBuffer();
if (getData(dataNum) != null && getData(dataNum).length() >MAX_LENGTH) {
buf.append(getData(dataNum).substring(0, MAX_LENGTH));
} else {
buf.append(getData(dataNum));
}
System.out.println(buf.toString());
} public List<String> getFields() {
final List<String> fields = new ArrayList<String>();
for (int i = 1; i <= numFields; i++) {
fields.add(getData(i));
}
return fields;
} public void setData(final int dataNum, final String data) {
switch (dataNum) {
case 1:
data1 = data;
break;
case 2:
data2 = data;
break;
case 3:
data3 = data;
break;
default:
break;
}
} public String getData(final int dataNum) {
switch (dataNum) {
case 1:
return getData1();
case 2:
return getData2();
case 3:
return getData3();
default:
return "";
}
}
public String getData1() {
return data1;
}
public void setData1(final String data1) {
this.data1 = data1;
}
public String getData2() {
return data2;
}
public void setData2(final String data2) {
this.data2 = data2;
}
public String getData3() {
return data3;
}
public void setData3(final String data3) {
this.data3 = data3;
}
}
private static final int MAX_LENGTH = 65535;
private String data1;
private String data2;
private String data3;
private final int numFields;
public ContentMap(final Content content, final int numFields) {
this.numFields = numFields;
if (content != null) {
for (int i = 1; i <= numFields; i++) {
final ContentField field = content.getField(i);
if (field != null)
setData(i, field.getData());
}
}
} public void displayField(final int dataNum) {
final StringBuffer buf = new StringBuffer();
if (getData(dataNum) != null && getData(dataNum).length() >MAX_LENGTH) {
buf.append(getData(dataNum).substring(0, MAX_LENGTH));
} else {
buf.append(getData(dataNum));
}
System.out.println(buf.toString());
} public List<String> getFields() {
final List<String> fields = new ArrayList<String>();
for (int i = 1; i <= numFields; i++) {
fields.add(getData(i));
}
return fields;
} public void setData(final int dataNum, final String data) {
switch (dataNum) {
case 1:
data1 = data;
break;
case 2:
data2 = data;
break;
case 3:
data3 = data;
break;
default:
break;
}
} public String getData(final int dataNum) {
switch (dataNum) {
case 1:
return getData1();
case 2:
return getData2();
case 3:
return getData3();
default:
return "";
}
}
public String getData1() {
return data1;
}
public void setData1(final String data1) {
this.data1 = data1;
}
public String getData2() {
return data2;
}
public void setData2(final String data2) {
this.data2 = data2;
}
public String getData3() {
return data3;
}
public void setData3(final String data3) {
this.data3 = data3;
}
}
我的终极问题是:
这个类本身存在的价值不大。
import java.util.*;/**
* 第七点:代码总体风格应该保持前后一致,如getData和setData两个方法中,对switch逻辑的处理风格完全不同。
* 第八点:几乎所有变量和参数都是final,有必要吗?
* 第十二点:整个类的意义是什么,还不如直接使用Content这个类来封装这些方法。
* @author jinxfei
*
*/
public abstract class ContentMap {
private static final int MAX_LENGTH = 65535;
private String data1;//第一点:data1 data2 data3的命名让人疑惑
private String data2;
private String data3;
private final int numFields; /**
*第二点:Content既然已经封装成类,则numFields不应该作为独立变量传进来,这样不易保证程序完整性
*第十一点:如果这个对象构造的时候numFields>3,数据丢失,因为getFields方法会将超出的数据返回为空串。既然定死只有data1-3,那么应该在这个方法中做长度检查
* @param content
* @param numFields
*/
public ContentMap(final Content content, final int numFields) {
this.numFields = numFields;
if (content != null) {
for (int i = 1; i <= numFields; i++) {
final ContentField field = content.getField(i);
if (field != null)
setData(i, field.getData());
}
}
} /**
* 第四点:根据这个方法的逻辑,使用StringBuffer的意义不大,反而会增加程序的可读性
* 第五点:getData(dataNum)被多次调用,增加了不必要的开销
* @param dataNum
*/
public void displayField(final int dataNum) {
final StringBuffer buf = new StringBuffer();
if (getData(dataNum) != null && getData(dataNum).length() > MAX_LENGTH) {
buf.append(getData(dataNum).substring(0, MAX_LENGTH));
} else {
buf.append(getData(dataNum));
}
System.out.println(buf.toString());
} public List<String> getFields() {
final List<String> fields = new ArrayList<String>();
for (int i = 1; i <= numFields; i++) {
fields.add(getData(i));
}
return fields;
} /**
*第三点:既然已经有data1-3的set get方法,该方法内不应该再给data1-3直接赋值。
*第九点:由于dataNum不为1/2/3时,程序实际上没有执行任何动作,数据被丢弃,但没有任何提示,不利于调试发现问题,建议抛出异常
* @param dataNum
* @param data
*/
public void setData(final int dataNum, final String data) {
switch (dataNum) {
case 1:
data1 = data;
break;
case 2:
data2 = data;
break;
case 3:
data3 = data;
break;
default:
break;
}
} /**
* 第六点:该方法功能没问题,但建议遵循单点返回的原则,不应在每个case中return。
* 第十点:当dataNum超过范围后,返回空串,无法判断是数据本身就是空串,还是dataNum超限,建议抛出异常
* @param dataNum
* @return
*/
public String getData(final int dataNum) {
switch (dataNum) {
case 1:
return getData1();
case 2:
return getData2();
case 3:
return getData3();
default:
return "";
}
} public String getData1() {
return data1;
} public void setData1(final String data1) {
this.data1 = data1;
} public String getData2() {
return data2;
} public void setData2(final String data2) {
this.data2 = data2;
} public String getData3() {
return data3;
} public void setData3(final String data3) {
this.data3 = data3;
}
}