適配器模式,這個(gè)模式也很簡(jiǎn)單,你筆記本上的那個(gè)拖在外面的黑盒子就是個(gè)適配器,1般你在中國(guó)能用,在日本也能用,雖然兩個(gè)國(guó)家的的電源電壓不同,中國(guó)是 220V,日本是 110V,但是這個(gè)適配器能夠把這些不同的電壓轉(zhuǎn)換為你需要的 36V 電壓,保證你的筆記本能夠正常運(yùn)行,那我們?cè)谠O(shè)計(jì)模式中引入這個(gè)適配器模式是否是也是這個(gè)意思呢?是的,1樣的作用,兩個(gè)不同接口,有不同的實(shí)現(xiàn),但是某1天突然上帝命令你把 B 接口轉(zhuǎn)換為 A 接口,怎樣辦?繼承,能解決,但是比較傻,而且還背背了 OCP 原則,怎樣辦?好在我們還有適配器模式。
適配器的通用類圖是這個(gè)模樣滴:
Target 是1個(gè)類(接口) ,Adaptee 是1個(gè)接口,通過(guò) Adapter 把 Adaptee 包裝成 Target 的1個(gè)子類(實(shí)現(xiàn)類) ,注意了這里用了個(gè)名詞包裝(Wrapper) ,那其實(shí)這個(gè)模式也叫做包裝模式(Wrapper),但是包裝模式可不知1個(gè),還包括了以后要講的裝潢模式。我來(lái)說(shuō)個(gè)自己的1個(gè)經(jīng)驗(yàn),讓大家可以更容易了解這個(gè)適配器模式,否則純講技術(shù)太枯燥了,技術(shù)也能夠有文娛的嘛。
我在 2004 年的時(shí)候帶了1個(gè)項(xiàng)目,做1個(gè)人力資源管理,該項(xiàng)目是我們總公司發(fā)起的項(xiàng)目,公司1共有 700 多號(hào)人,包括子公司,這個(gè)項(xiàng)目還是比較簡(jiǎn)單的,分為3大模塊:人員信息管理,薪酬管理,職位管理,其中人員管理這塊就用到了適配器模式,是怎樣回事呢?當(dāng)時(shí)開發(fā)時(shí)明確的指明:人員信息簡(jiǎn)管理的對(duì)象是所有員工的所有信息,然后我們就這樣設(shè)計(jì)了1個(gè)類圖:
還是比較簡(jiǎn)單的,有1個(gè)對(duì)象 UserInfo 存儲(chǔ)用戶的所有信息(實(shí)際系統(tǒng)上還有很多子類,不多說(shuō)了),也就是BO(Business Object) ,這個(gè) UserInfo 對(duì)象,在系統(tǒng)中很多地方使用,你可以查看自己的信息,也能夠做修改,固然這個(gè)對(duì)象是有 setter 方法的,我們這里用不到就隱藏掉了。
這個(gè)項(xiàng)目是 04 年年底投產(chǎn)的,運(yùn)行到 05 年年底還是比較安穩(wěn)的,中間修修補(bǔ)補(bǔ)也很正常,05 年年底不知道是那股風(fēng)吹的,很多公司開始使用借聘人員的方式招聘人員,我們公司也不例外,從1個(gè)人力資源公司借用了1大批的低技術(shù)、低工資的人員,分配到各個(gè)子公司,總共有將近 200 號(hào)人,然后就找我們部門老大談判,說(shuō)要增加1個(gè)功能借用人員管理,老大1看有錢賺呀,1拍大腿,做!
我?guī)诉^(guò)去1調(diào)研,不是這么簡(jiǎn)單,人力資源公司有1套自己的人員管理系統(tǒng),我們公司需要把我們使用到的人員信息傳輸?shù)轿覀兊南到y(tǒng)中,系統(tǒng)之間的傳輸使用 RMI(Remote Method Invocation,遠(yuǎn)程對(duì)象調(diào)用)的方式,但是有1個(gè)問(wèn)題人力資源公司的人員對(duì)象和我們系統(tǒng)的對(duì)象不相同呀,他們的對(duì)象是這樣的:
人員資源公司是把人的信息分為了3部份: 基本信息, 辦公信息和個(gè)人家庭信息, 并且都放到了 HashMap中,比如人員的姓名放到 BaseInfo信息中,家庭地址放到 HomeInfo 中,這咱不好說(shuō)他們系統(tǒng)設(shè)計(jì)的不好,那問(wèn)題是咱的系統(tǒng)要和他們系統(tǒng)有交互,怎樣辦?使用適配器模式,類圖以下:
大家可能會(huì)問(wèn),這兩個(gè)對(duì)象都不在1個(gè)系統(tǒng)中,你如何使用呢?簡(jiǎn)單!RMI 已幫我們做了這件事情,只要有接口,就能夠把遠(yuǎn)程的對(duì)象當(dāng)做本地的對(duì)象使用,這個(gè)大家有時(shí)間可以去看1下 RMI 文檔,不多說(shuō)了。通過(guò)適配器,把 OuterUser 假裝成我們系統(tǒng)中1個(gè) IUserInfo 對(duì)象,這樣,我們的系統(tǒng)基本不用修改甚么程序,所有的人員查詢、調(diào)用跟本地1樣樣的,說(shuō)的口干舌燥,那下邊我們來(lái)看具體的代碼實(shí)現(xiàn):
首先看 IUserInfo.java 的代碼:
然后看這個(gè)接口的實(shí)現(xiàn)類:
可能有人要問(wèn)了,為何要把電話號(hào)碼、手機(jī)號(hào)碼都設(shè)置成 String 類型,而不是 int 類型,大家覺(jué)的呢?題外話,這個(gè)絕對(duì)應(yīng)當(dāng)是 String 類型,包括數(shù)據(jù)庫(kù)也應(yīng)當(dāng)是 varchar 類型的,手機(jī)號(hào)碼有小靈通帶區(qū)號(hào)的,比如 02100001,這個(gè)你用數(shù)字怎樣表示?有些人要在手機(jī)號(hào)碼前加上 0086 后再保存,比如我們公司的印度阿3就是這樣,喜歡在手機(jī)號(hào)碼前 0086保存下來(lái),呵呵,我是想到啥就說(shuō)啥,