首先解釋一下,文本中的信息指的是 對象在文本文件中的描述,如"名稱:Bill 職位:SSE 年齡:45 薪水:10000"這個形式的.要求把這樣的信息轉(zhuǎn)換到對象Member中,對錄入出錯的情況如年齡薪水有非數(shù)字字符需要加以鑒別.
對象基本信息如下:

public class Member implements Comparable
{
// 名稱
private String name;

// 年齡
private int age;

// 職位
private String title;

// 薪水
private int salary;
.
}
從這段字符串中找到相關(guān)的信息并設(shè)置到Member對象的相關(guān)屬性中并不難,但有幾個地方需要多加考慮:
1.名稱職位薪水年齡的順序不一定一致.
2.職位薪水年齡三個字段和值有可能沒有.
3.有可能需要增加字段,此時類也需要修改.
處理程序需要考慮解析,驗證,賦值三個環(huán)節(jié),如果耦合在一起處理當(dāng)然也能做出來,但這樣做可讀性和可維護(hù)性都不好,也背離了面向?qū)ο蟮某踔?好的方案應(yīng)該把這三部分分開制作函數(shù)處理.
文本解析部分:
我的想法是首先將"名稱:Bill 職位:SSE 年齡:45 薪水:10000"以空格劈分成包含這樣元素的鏈表:
名稱:Bill
職位:SSE
年齡:45
薪水:10000
然后在用冒號":"劈分單個元素,前半部分作為鍵,后半部分作為值,放入一個Hashtable中:
key value
名稱 Bill
職位 SSE
年齡 45
薪水 10000
解析部分代碼如下:

/** *//**
* 將分段字符串鏈表轉(zhuǎn)化成成員鏈表,不成功者記入錯誤鏈表
*
* @param segmentList
* 分段字符串鏈表
*/

private void changeSegmentToMember(List<String> segmentList)
{

for (String segment : segmentList)
{
Map<String, String> ht = StringUtil.parseStr2Map(segment, " ", ":");

Member member = new Member();


if (member.setHtToProperties(ht))
{
// 成功賦值,將成員放入成員列表
memberList.add(member);

} else
{
// 有任何錯誤,將分段信息放入錯誤鏈表
errorList.add(segment);
}
}
}
賦值和驗證部分:
然后把這個Hashtable傳入到Member的一個函數(shù)setHtToProperties中,這個函數(shù)的任務(wù)是對Hashtable中的鍵值對進(jìn)行遍歷,在調(diào)用函數(shù)setValueToProperty對字段進(jìn)行賦值:
代碼如下:

/** *//**
* 將哈息表中成對的值按規(guī)則輸入屬性
* @param ht
* @return
*/

public boolean setHtToProperties(Map<String,String> ht)
{
Iterator it=ht.keySet().iterator();

while(it.hasNext())
{
String key=(String)it.next();
String value=(String)ht.get(key);
boolean isSettted=setValueToProperty(key,value);

if(isSettted==false)
{
return false;
}
}
return true;
}

/** *//**
* 在mapping關(guān)系中用屬性名去找屬性對應(yīng)的變量,是則賦值;如找不到或轉(zhuǎn)化出錯則返回假
* @param propertyName 屬性名,如name對應(yīng)的名稱
* @param propertyNalue 屬性值,如那么對應(yīng)的Bill
* @return
*/

private boolean setValueToProperty(String propertyName,String propertyNalue)
{

if(propertyName.equals("名稱"))
{
name=propertyNalue;
}

else if(propertyName.equals("年齡"))
{

try
{
int ageTemp=Integer.parseInt(propertyNalue);
age=ageTemp;
}

catch(Exception e)
{
return false;
}
}

else if(propertyName.equals("職位"))
{
title=propertyNalue;
}

else if(propertyName.equals("薪水"))
{

try
{
int salaryTemp=Integer.parseInt(propertyNalue);
salary=salaryTemp;
}

catch(Exception e)
{
return false;
}
}

else
{
return false;
}

return true;
}
建立setValueToProperty函數(shù)的初衷是,用分支語句建立起鍵值與字段的對應(yīng)關(guān)系,對應(yīng)上了則進(jìn)行賦值,這和Mapping有點類似,有些轉(zhuǎn)化和驗證工作也在分支內(nèi)進(jìn)行,只要驗證出現(xiàn)問題即退出處理.
這樣的處理方法帶來了如下好處:
1.外界的類只需要解析文本,不需也不應(yīng)該知道如何向Member的對應(yīng)字段賦值,這個工作應(yīng)該由Member自己進(jìn)行,setHtToProperties函數(shù)幫助達(dá)成了這一點,有效降低了Member和其它類的耦合程度.
2.即使職位薪水年齡三個字段和值缺失,也不影響其它字段的賦值過程.
3.如果增加字段,setValueToProperty函數(shù)中只需要增加一個Mapping分支即可,其它地方無須改動.
4.對數(shù)據(jù)的校驗工作可以統(tǒng)一在setValueToProperty函數(shù)中完成.
進(jìn)行了如此處理后,代碼量也不見得比混合處理多多少,而程序更加清晰,適應(yīng)性也增強(qiáng)了,經(jīng)得起不斷更改. 比解析驗證賦值混合在一起的方案要強(qiáng)的多.
完整代碼下載:
http://www.tkk7.com/Files/sitinspring/MemberProcessor20071207163615.rar