BadRegExpMatcher dateMatcher = new BadRegExpMatcher(...);
while (...) {
...
String headerLine = new String(myBuffer, thisHeaderStart,
thisHeaderEnd-thisHeaderStart);
String result = dateMatcher.match(headerLine);
if (result == null) { ... }
}
其次,即使MailBot僅僅需要得到是否匹配的返回信息,而無需得到匹配的文本,匹配器也會返回一個匹配的字符串。這意味著為了簡單地使用BadRegExpMatcher來驗證一個特定格式的日期標題,你也必須創建二個 String對象━━供匹配器使用的輸入文本和匹配結果文本。創建二個對象似乎不會對性能產生重大影響,但如果必須為MailBot處理的每條郵件的標題創建二個對象,就可能嚴重地影響程序的性能。這一問題并不出在MailBot本身的設計上,而是出在BadRegExpMatcher的設計上。
注意:不返回String對象而返回一個"輕量級"的Match對象也不會在性能上帶來很大的改進。盡管創建一個Match對象的代價要比創建一個String對象的代價低一些,它還是會產生一個char數組,并拷貝數據,仍然創建了一個對調用者并非必需的臨時性的對象。
BadRegExpMatcher只接受它需要的輸入數據類型,而不是可以接受我們方便提供的數據類型,僅就這一點,它就非常不理想。使用BadRegExpMatcher還會帶來別的危害,其中的一個潛在的危害是這樣將對MailBot的性能帶來更多的影響。盡管在處理郵件的標題時必須避免使用Strings,但又必須創建許多的Strings對象供BadRegExpMatcher使用,因此你可能放棄不使用String對象的目標,而更加不受限制地使用它。一個設計不恰當的組件會影響使用它的程序的性能,即使以后找到了一個無需使用String對象的表達式組件,整個程序仍然會受到影響。
一個恰當的接口
如何定義BadRegExpMatcher才能避免上述的問題呢?首先,BadRegExpMatcher應該不指定其輸入文本的格式,它應該能夠接受其調用者可以高效地提供的任何一種數據類型。其次,它不應該為匹配結果自動地生成一個String對象,只需要返回足夠的信息讓調用者來決定是否需要生成匹配結果字符串。(也可以提供一個方法來完成這一任務,但這并非是必需的。)一個性能比較好的接口應該是這樣的:
class BetterRegExpMatcher {
public BetterRegExpMatcher(...);
/** 使匹配器可以接受多種格式的輸入━━ String對象、字符數組、字符組數的子集,如果不匹配,返回-1;如果匹配,則返回開始匹配的偏移地址。*/
public int match(String inputText);
public int match(char[] inputText);
public int match(char[] inputText, int offset, int length);
/** 如果匹配,則返回匹配的長度;如果不是完全匹配,則調用程序應該能夠從匹配的偏移處生成匹配的字符串 */
public int getMatchLength();
/** 如果調用程序需要,就可以很方便地得到匹配字符串的子程序 */
public String getMatchText();
}
文章來源于領測軟件測試網 http://www.kjueaiud.com/