前言 這篇博客的目的是對項目中偶爾碰到的應用設計模式的代碼積累一下。 我認為針對於設計模式的學習,通過看書、看例子只能瞭解概念,而重要的是如何把概念應用到實際的項目開發中。 而且我想提醒大家的是,學習設計模式時,千萬不要拘泥於書上的內容,形成定式思維,這樣對於其他源碼理解會出現一層自然屏障,理解起來 ...
前言
這篇博客的目的是對項目中偶爾碰到的應用設計模式的代碼積累一下。
我認為針對於設計模式的學習,通過看書、看例子只能瞭解概念,而重要的是如何把概念應用到實際的項目開發中。
而且我想提醒大家的是,學習設計模式時,千萬不要拘泥於書上的內容,形成定式思維,這樣對於其他源碼理解會出現一層自然屏障,理解起來很困難。
大家在看JDK源碼和Spring源碼時會發現,很少照搬書上的內容,都是靈活運用。
這也是我計劃寫這類博客的原因,希望通過項目中的實際需求去理解,並應用設計模式!
開篇之作--簡單工廠模式的應用
需求:我們項目中有個消費記錄解析上傳的功能,我們需要給客戶端開發一個介面。客戶端調用介面,將多條消費記錄以參數傳入介面,然後介面
解析參數中的數據,並將數據存儲到資料庫中。項目中存在多種業務,一種業務對應一種解析規則,以後還可能會新加業務類型。
分析:針對於這個需求,如果沒有學習過設計模式,可能這樣實現。第一種,項目當前有4種業務,那麼就寫4個介面,一個介面實現一種解析規則,
客戶端根據不同的規則調用不同的介面;第二種,改進些,那麼就給客戶端暴漏一個介面,客戶端將類型傳入介面,方法中根據類型調用不同的解析規則。
那麼第一種方法的問題是什麼呢?項目有4種業務寫4個介面,如果有10個業務就寫10個介面,這些介面實現的業務功能又是一樣的,那麼這是很明顯
的代碼重覆,介面冗餘,成功的給項目重構挖了一個坑。
第二種方法呢,確實解決了上面說的問題,但是實現上又導致了介面對規則的依賴,所以也是不可取的。
那麼我們項目中是如何實現的呢?請往下看…
項目實現:
註:代碼主要表達思想,大家不要摳具體的類名、標簽名等等,主要理解實現思路,本人以前就經常犯鑽牛角尖的毛病!
1、首先是暴漏給客戶端的介面
public class ConsumeHistoryAction extends BaseExecutableAction{ private Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private ConsumeHistoryService consumeHistoryService; @Autowired private TransDetailResolverFactory transDetailResolverFactory; public void upload(Map map) throws CoreException{ // 獲取業務類型 String type = map.get(“type”); // 獲取要解析的數據 String data = map.get(“data”); // 根據業務類型獲取解析規則類(一個業務類型對應一個解析類) TransDetailResolver resolver = transDetailResolverFactory.getResolver(type); if(resolver==null){ logger.error("No TransDetailResolver defined for {}", type); return; } // 解析數據,將數據放到一個實體類中 ConsumeHistory consumeRecord = resolver.resolver(data); // 保存數據到資料庫 consumeHistoryService.upload(consumeRecords); } }
2、解析工廠類的實現
public class TransDetailResolverFactory { // 通過spring配置,將具體的業務類型與解析規則類的對應關係註入進來 // 這樣就有效避免了工廠類和規則類之間的依賴 private Map<String,TransDetailResolver> resolvers = new HashMap<String,TransDetailResolver>(); public interface TransDetailResolver { public ConsumeHistory resolver(String str); } public void setResolvers(Map<String, TransDetailResolver> resolvers) { this.resolvers = resolvers; } public TransDetailResolver getResolver(String aid){ // 其實這塊依賴的處理,也可以通過反射來實現
TransDetailResolver resolver = resolvers.get(aid); return resolver; } }
3、依賴關係的配置
<x:bean class="com.xxx.TransDetailResolverFactory"> <x:property name="resolvers"> <x:map> // 本項目的業務類型其實是一串CODE碼 <x:entry key="1001"> <x:bean class="com.xxx.consumehistory.aaaResolver"> </x:bean> </x:entry> <x:entry key="1002"> <x:bean class="com.xxx.consumehistory.bbbResolver"> </x:bean> </x:entry> <x:entry key="1003"> <x:bean class="com.xxx.consumehistory.cccResolver"> </x:bean> </x:entry> </x:map> </x:property> </x:bean>
4、解析規則類的實現
這個我就不具體上代碼了,就是根據具體的業務規則實現代碼的解析規則就可以了。
特別註意的是,這個類一定要實現工廠類中的介面,為什麼要實現?這個問題留給閱讀的同學思考吧!嘿嘿嘿!
總結:以上就是具體的實現思路了,雖然簡單,但是代碼結構很清晰,如果未來要加一種業務類型,只需要創建對應的解析規則類,再修改下配置
文件就搞定了,其他的代碼都不需要改動。
首篇博客,廢話較多,以後會直接上乾貨!!!
有哪些不足,請大家多多指點!!!