道生一,一生萬(wàn)。
摘要:
本文將繼續(xù)以O(shè)PENCSV為案例,介紹建造模式(Builder Pattern)以及在OPENCSV中的簡(jiǎn)化模式。
1. 建造模式模式簡(jiǎn)介
建造模式屬于創(chuàng)建類型的設(shè)計(jì)模式。其余創(chuàng)建型模式還有工廠模式、單例模式、原型模式等,顧名思義,就是當(dāng)需要new一些對(duì)象的實(shí)例時(shí),可以考慮使用這些類型的設(shè)計(jì)模式。 和同類型的模式相比,建造模式的特點(diǎn)就是“將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示”。其類圖表示如下

為了創(chuàng)建Product對(duì)象,定義一個(gè)Builder接口,并且在接口中定義了創(chuàng)建Product各個(gè)組成部分的方法BuildPart(可以有多個(gè),負(fù)責(zé)不同部分的構(gòu)建)。ConcreteBuilder則是具體的Builder類的實(shí)現(xiàn)。而Director類使用Builder接口的具體對(duì)象,來(lái)完成某個(gè)具體Product產(chǎn)品的構(gòu)建過(guò)程(for循環(huán)部分)。
2. 建造模式在Opencsv中的應(yīng)用
1) CsvToBeanBuilder與CsvToBean
在OpenCSV中也廣泛用到了這一模式。舉例來(lái)說(shuō),CsvToBean<T>是OpenCSV這個(gè)工具的核心類之一。顧名思義,其主要職責(zé)就是負(fù)責(zé)將CSV數(shù)據(jù)解析成為對(duì)應(yīng)的T類型的對(duì)象(bean)。為了能夠順利完成這一工作,在初始化該類時(shí),需要配置許多參數(shù),如匹配策略MappingStrategy,對(duì)應(yīng)的Bean類等等。OpenCSV提供了CsvToBeanBuilder這一建造類,方便完成這個(gè)初始化的工作。這個(gè)類的部分方法如下圖所示,

其中的各種以with開頭的方法就是完成CsvToBean對(duì)象的某個(gè)組成部分的構(gòu)建任務(wù),如withSeparator(char)就是指定CSV數(shù)據(jù)的分隔符號(hào),如常見(jiàn)的","或者“;”。
2) 測(cè)試用例(Director)
在定義了構(gòu)建類和具體的構(gòu)建方法后,就可以在外部通過(guò)Director完成產(chǎn)品CsvToBean的構(gòu)建過(guò)程了。在OpenCSV提供的單元測(cè)試用例中,給出了如下的使用案例,
@Test
**public** **void** testColumnMappingStrategyWithBuilder() **throws** FileNotFoundException {
List<AnnotatedMockBeanFull> result =
**new** CsvToBeanBuilder<AnnotatedMockBeanFull>(**new** FileReader("src/test/resources/testinputposfullgood.csv"))
.withSeparator(';')
.withType(AnnotatedMockBeanFull.**class**)
.build()
.parse();
*assertEquals*(2, result.size());
}
通過(guò)調(diào)用CsvToBeanBuilder提供的各個(gè)withXXX構(gòu)建方法以及build方法,構(gòu)造出了一個(gè)匿名的CsvToBean實(shí)例,并通過(guò)調(diào)用其parse()方法完成對(duì)提供的.csv文件的解析,將其每一行數(shù)據(jù)解析成為一個(gè)AnnotatedMockBeanFull類的實(shí)例,并存放進(jìn) result中。
3) 案例點(diǎn)評(píng)
在這個(gè)案例中,建造模式簡(jiǎn)化成為了如下的形式,

即,去掉了Builder接口,直接定義了CsvToBeanBuilder這一ConcreateBuilder類,來(lái)對(duì)需要構(gòu)建的產(chǎn)品Product產(chǎn)品,即CsvToBean進(jìn)行構(gòu)建。這一過(guò)程的的導(dǎo)演Director,則由具體的測(cè)試用例類在工具外部完成。這樣,對(duì)于靈活多樣的CSV數(shù)據(jù)文件,可以建造出來(lái)各種不同的Product來(lái)實(shí)施解析,提高了工具使用的便利性。在CsvToBean中,之前存在著許多重載的parse方法,實(shí)現(xiàn)對(duì)CSV文件的不同方式的解析。而通過(guò)使用CsvToBeanBuilder之后,則只要通過(guò)其構(gòu)造出所需要的CsvToBean實(shí)例,并調(diào)用無(wú)參的parse方法即可完成。

從而屏蔽了具體的parse實(shí)現(xiàn),實(shí)現(xiàn)了解析過(guò)程和數(shù)據(jù)內(nèi)容和方式的解耦合。
類似的,Opencsv中還使用了CSVParserBuilder、CSVReaderBuilder等來(lái)建造類來(lái)提供CSVParser、CSVReader等類的實(shí)例,也都是采用了前述介紹的簡(jiǎn)化模式。感興趣的讀者可以閱讀OPENCSV的源碼進(jìn)一步了解。