JAVA設(shè)計(jì)模式:工廠模式之簡(jiǎn)單工廠
序
在java中,設(shè)計(jì)模式是多態(tài)和封裝的重要表現(xiàn)形式,采用設(shè)計(jì)模式能夠極大地提升可維護(hù)性和可擴(kuò)展性,那么,同樣工作在jvm上面的Clojure能否運(yùn)用這些模式,或者說是否同樣需要這些模式呢?
注:本文基于jdk1.6和Clojure1.2
簡(jiǎn)單工廠
先看看簡(jiǎn)單工廠的java代碼:
首先定義產(chǎn)品的接口:
- public interface IProduct {
- /**
- * 使用產(chǎn)品
- * @param msg
- */
- public void use(String msg);
- }
然后是實(shí)現(xiàn)了這個(gè)接口的兩個(gè)具體產(chǎn)品Product1和Product2:
- public class Product1 implements IProduct {
- @Override
- public void use(String msg) {
- System.out.println("Product1 use:"+msg);
- }
- }
- public class Product2 implements IProduct {
- @Override
- public void use(String msg) {
- System.out.println("Product2 use:"+msg);
- }
- }
***是根據(jù)類型獲取產(chǎn)品的簡(jiǎn)單工廠:
- public class SimpleFactory {
- /**
- * 根據(jù)產(chǎn)品類型生產(chǎn)產(chǎn)品
- * @param productType
- * @return
- */
- public static IProduct factory(String productType){
- if(productType.equals("1"))
- return new Product1();
- else if(productType.equals("2"))
- return new Product2();
- return null;
- }
- }
這樣,我們?cè)趈ava中就構(gòu)建了能夠生產(chǎn)出兩個(gè)不同產(chǎn)品的簡(jiǎn)單工廠了。接下來,我們調(diào)用一下:
- /**
- * 簡(jiǎn)單工廠調(diào)用
- * @author RoySong - 2011-10-27
- */
- public class SimpleFactoryTest {
- /**
- * @param args
- */
- public static void main(String[] args) {
- IProduct product1 = SimpleFactory.factory("1");
- product1.use("something");
- IProduct product2 = SimpleFactory.factory("2");
- product2.use("something");
- }
- }
運(yùn)行這個(gè)調(diào)用程序,我們能夠得到預(yù)期的結(jié)果:
- Product1 use:something
- Product2 use:something
那么,在Clojure中應(yīng)該如何實(shí)現(xiàn)呢?
#p#
首先,讓我們?cè)倩仡櫼幌虏捎煤?jiǎn)單工廠的目的,這是為了將業(yè)務(wù)對(duì)象的產(chǎn)生和業(yè)務(wù)方法的執(zhí)行進(jìn)行解耦,使得業(yè)務(wù)方法執(zhí)行時(shí)無須關(guān)注業(yè)務(wù)對(duì)象的類型。為了達(dá)到這個(gè)目的,我們提取了業(yè)務(wù)對(duì)象的接口IProduct(在實(shí)際的應(yīng)用中也有可能是一個(gè)父類Product),它的里面包含了所有業(yè)務(wù)對(duì)象的共同操作use(在實(shí)際應(yīng)用中可能不止這一種業(yè)務(wù)操作,當(dāng)然也不叫use)的方法聲明。然后,由SimplyFactory來創(chuàng)建IProduct的實(shí)例對(duì)象,然后調(diào)用use業(yè)務(wù)方法。在這個(gè)時(shí)候,調(diào)用方法是無須關(guān)注被調(diào)用的具體是哪個(gè)實(shí)例對(duì)象--Product1還是Product2。
好吧,為了業(yè)務(wù)對(duì)象的產(chǎn)生和業(yè)務(wù)方法的執(zhí)行解耦。然后,Clojure中沒有對(duì)象一說,方法倒是有,不過叫做函數(shù)。于是,問題解決了,沒有對(duì)象,則無須對(duì)對(duì)象的產(chǎn)生進(jìn)行解耦。本文結(jié)束。
拋開上面的文字游戲不談,實(shí)際上Clojure的解決方式更為靈活,這是由其語言特性所決定的。在java中,一切都是對(duì)象(除了原始類型),而類和接口是對(duì)象的定義,包含了有關(guān)對(duì)象動(dòng)作方式的相關(guān)信息,比如名稱、方法、屬性和事件等。所以,在java應(yīng)用中,能夠使用的最小粒度的東西就是對(duì)象,如果需要調(diào)用某個(gè)實(shí)例方法,首先需要實(shí)例化某個(gè)對(duì)象,然后調(diào)用這個(gè)對(duì)象的方法;如果需要調(diào)用某個(gè)靜態(tài)方法,需要找到靜態(tài)方法所屬的類,然后以類名.方法名的形式來調(diào)用。而在Clojure中,函數(shù)是***類對(duì)象,它無須依附對(duì)象或者類而存在(實(shí)際上,在幾乎所有的函數(shù)式編程語言中都是這樣)。換句話說,我們調(diào)用某個(gè)方法無須首先實(shí)例化某個(gè)對(duì)象或者找到某個(gè)類。
那么,針對(duì)上面的例子,我們可以說,實(shí)際上我們需要的是根據(jù)不同的類型獲取兩個(gè)不同的業(yè)務(wù)處理方法而已。
- (defn simply-factory [type]
- (cond
- (= 1 type) (fn [msg] (println "Product1 use:" msg))
- (= 2 type) (fn [msg] (println "Product2 use:" msg))))
在上面的代碼中,我們定義了一個(gè)函數(shù)simply-factory,它接受一個(gè)參數(shù)type,然后根據(jù)type的值為1或者2返回對(duì)應(yīng)的函數(shù)。實(shí)際上,我們從內(nèi)容上可以看出來,這兩個(gè)函數(shù)就分別對(duì)應(yīng)了之前我們定義的Product1和Product2中的use方法。
接下來,我們就看看調(diào)用和產(chǎn)生的輸出:
- user> ((simply-factory 1) "something")
- Product1 use: something
- nil
- user> ((simply-factory 2) "something")
- Product2 use: something
- nil
已經(jīng)達(dá)到了我們之前想要的結(jié)果,對(duì)不對(duì)?讓我們?cè)倏纯凑{(diào)用方法的代碼((simply-factory 1) "something"),(simply-factory 1)代表傳入?yún)?shù)1調(diào)用simply-factory函數(shù),返回的是一個(gè)匿名函數(shù);而((simply-factory 1) "something")整體就代表將"something"傳入simply-factory函數(shù)返回的匿名函數(shù),然后我們就得到了預(yù)期的結(jié)果:Product1 use: something。我相信你已經(jīng)看出來了,Clojure中函數(shù)的調(diào)用方式是:(函數(shù)名 參數(shù))這個(gè)樣子的。
不過這個(gè)樣子跟上面的java代碼似乎差別有點(diǎn)大,讓我們對(duì)這個(gè)調(diào)用方式做一點(diǎn)小小的修改:
- user> (def product1 (simply-factory 1))
- #'user/product1
- user> (product1 "something")
- Product1 use: something
- nil
- user> (def product2 (simply-factory 2))
- #'user/product2
- user> (product2 "something")
- Product2 use: something
- nil
這樣子應(yīng)該就能夠和之前的java代碼一一對(duì)應(yīng)了,其中
- IProduct product1 = SimpleFactory.factory("1");
對(duì)應(yīng)
- (def product1 (simply-factory 1))
,而
- product1.use("something");
對(duì)應(yīng)
- (product1 "something")
這樣子是不是就能看得更明白一些了?不過要注意的是,雖然調(diào)用形式看起來很類似,但是在Clojure中product1是個(gè)函數(shù),而java中product1是個(gè)對(duì)象。
原文鏈接:http://songry.iteye.com/blog/1218694
編輯推薦:


























