日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
一次代碼優(yōu)化實(shí)踐,用了模板方法+策略+工廠方法模式

前言

好久沒分享工作總結(jié)啦,今天來一份代碼優(yōu)化總結(jié)。用模板方法+策略+工廠方法模式優(yōu)化了代碼,耐心點(diǎn)看完,應(yīng)該對(duì)大家有幫助的~

本文已經(jīng)收錄到github

https://github.com/whx123/JavaHome

優(yōu)化代碼前

先來了解一下類似的業(yè)務(wù)場景,簡言之,就是:多個(gè)商戶接入我們系統(tǒng),都是走一個(gè)類似的流程通過http請(qǐng)求出去的。

優(yōu)化前,每個(gè)公司對(duì)應(yīng)一個(gè)句柄服務(wù),偽代碼如下:

 
 
 
 
  1. // 商戶A處理句柄 
  2. CompanyAHandler implements RequestHandler { 
  3.    Resp hander(req){ 
  4.    //查詢商戶信息 
  5.    queryMerchantInfo(); 
  6.    //加簽 
  7.    signature(); 
  8.    // http請(qǐng)求(走代理) 
  9.    httpRequestbyProxy() 
  10.    // 驗(yàn)簽 
  11.    verify(); 
  12.    } 
  13. // 商戶B處理句柄 
  14. CompanyBHandler implements RequestHandler { 
  15.    Resp hander(Rreq){ 
  16.    //查詢商戶信息 
  17.    queryMerchantInfo(); 
  18.    //加簽 
  19.    signature(); 
  20.    // http請(qǐng)求(不走代理) 
  21.    httpRequestbyDirect(); 
  22.    // 驗(yàn)簽 
  23.    verify();  
  24.    } 
  25. // 商戶C處理句柄 
  26. CompanyBHandler implements RequestHandler { 
  27.    Resp hander(Rreq){ 
  28.    //查詢商戶信息 
  29.    queryMerchantInfo(); 
  30.    // webservice 方式調(diào)用 
  31.    requestByWebservice(); 
  32.    } 

優(yōu)化代碼思路

我的優(yōu)化代碼思路,是有「重復(fù)代碼,先把它抽出來,或者公用變量,或者公用方法,伸著公用類」。所以呢,查詢商戶信息呀,加簽呀,http請(qǐng)求呀先全部各抽成一個(gè)公用方法。你細(xì)心點(diǎn)會(huì)發(fā)現(xiàn),連每個(gè)Handler處理過程都很類似的,大概都是查詢商戶信息+加簽+http請(qǐng)求+驗(yàn)簽,于是呢,可以直接把它們抽象成一個(gè)公用類呀~在這里就要引入模板方法模式咯

模板方法模式

 
 
 
 
  1. 在模板模式(Template Pattern)中,一個(gè)抽象類公開定義了執(zhí)行它的方法的方式/模板。它的子類可以按需要重寫方法實(shí)現(xiàn),但調(diào)用將以抽象類中定義的方式進(jìn)行。 
  2. 這種類型的設(shè)計(jì)模式屬于行為型模式。 

這種類型的設(shè)計(jì)模式屬于行為型模式。

既然每個(gè)Handler處理,都是類似的流程,那「定義一個(gè)抽象類,把查詢商戶信息,加簽,http請(qǐng)求,驗(yàn)簽什么的,都放到里面去,儼然一個(gè)模板一樣」。然后,因?yàn)橛行┥虘糇遠(yuǎn)ttp代理,有些又沒走代理,怎么辦呢? 定義「一個(gè)抽象方法,給子類實(shí)現(xiàn)」嘛,因?yàn)槟芄灿镁头诺礁割?當(dāng)前的抽象類),不能共用就放到子類嘛~代碼如下:

 
 
 
 
  1. abstract class AbstractCompanyCommonService implements ICompanyCommonService {  
  2.      //模板方法 
  3.      Resp handlerTempPlate(req){ 
  4.             //查詢商戶信息 
  5.            queryMerchantInfo(); 
  6.            // 加簽 
  7.            signature(); 
  8.            //http 請(qǐng)求 
  9.            if(isRequestByProxy()){ 
  10.               httpProxy(); 
  11.             }else{ 
  12.               httpDirect(); 
  13.              } 
  14.             // 驗(yàn)簽 
  15.             verifySinature(); 
  16.      } 
  17.       // Http是否走代理 
  18.       abstract boolean isRequestByProxy(); 

子類商戶A實(shí)現(xiàn):

 
 
 
 
  1. CompanyAServiceImpl extends AbstractCompanyCommonService{ 
  2.     Resp hander(req){ 
  3.       return handlerTempPlate(req); 
  4.     } 
  5.     //公司A是走代理的 
  6.     boolean isRequestByProxy(){ 
  7.        return true; 
  8.     } 

子類商戶B實(shí)現(xiàn):

 
 
 
 
  1. CompanyBServiceImpl extends AbstractCompanyCommonService{ 
  2.     Resp hander(req){ 
  3.       return handlerTempPlate(req); 
  4.     } 
  5.     //公司B是不走代理的 
  6.     boolean isRequestByProxy(){ 
  7.        return false; 
  8.     } 

策略模式

心細(xì)的讀者會(huì)發(fā)現(xiàn),甚至提出疑問,「你的商戶C的服務(wù)實(shí)現(xiàn)跟你定義的公用模板,不太一樣呢」,那當(dāng)然,實(shí)際開發(fā)中,不跟你定義的模板一樣太常見了,需求是產(chǎn)品提的嘛,又不是根據(jù)你模板提的,是代碼服務(wù)于需求的。好了,不多說啦,我使用了策略模式,來優(yōu)化這個(gè)問題。

 
 
 
 
  1. 在策略模式(Strategy Pattern)中,一個(gè)類的行為或其算法可以在運(yùn)行時(shí)更改。這種類型的設(shè)計(jì)模式屬于行為型模式。 

策略模式理解起來其好抽象對(duì)不對(duì)?我個(gè)人理解,其實(shí)策略模式就是定義一個(gè)方法(所謂算法),給子類自己去實(shí)現(xiàn)。實(shí)際上就是「定義個(gè)方法/接口,讓子類自己去實(shí)現(xiàn)」??创a吧:

 
 
 
 
  1. // 定義一個(gè)方法,把策略交給子類去實(shí)現(xiàn)。 
  2. interface ICompanyCommonService{ 
  3.   Resp hander(req); 

前面商戶A和商戶B還是不變,使用抽象類AbstractCompanyCommonService的模板,模板不滿足商戶C,商戶C只能自己去實(shí)現(xiàn)咯,各個(gè)子類自己去實(shí)現(xiàn)的行為,就是策略模式的體現(xiàn)呢,如下:

 
 
 
 
  1. CompanyCServiceImpl extends AbstractCompanyCommonService{ 
  2.     Res hander(req){ 
  3.        //查詢商戶信息 
  4.        queryMerchantInfo(); 
  5.        requestByWebservice();     
  6.     } 
  7.     //隨意了,你都不走模板了 
  8.     boolean isRequestByProxy(){ 
  9.        return false; 
  10.     } 

工廠方法模式

商戶A、B、C服務(wù)怎么被管理呢,之前分別給A,B,C服務(wù)實(shí)現(xiàn)handler的,現(xiàn)在好了,都不知道怎么管理了,怎么知道調(diào)用哪個(gè)呢?別慌,解決方案是「工廠方法模式」。

 
 
 
 
  1. 在工廠模式中,我們?cè)趧?chuàng)建對(duì)象時(shí)不會(huì)對(duì)客戶端暴露創(chuàng)建邏輯,并且是通過使用一個(gè)共同的接口來指向新創(chuàng)建的對(duì)象。 

工廠方法模式具體實(shí)現(xiàn)就是:接口定義一個(gè)枚舉,每個(gè)服務(wù)實(shí)現(xiàn)都重新實(shí)現(xiàn)枚舉,設(shè)置唯一標(biāo)志枚舉,再交給spring容器管理。看代碼咯:

 
 
 
 
  1. interface ICompanyCommonService{ 
  2.   Resp hander(req); 
  3.   CompanyEnum getCompanyEnum(); 
  4.  
  5. CompanyAServiceImpl extends AbstractCompanyCommonService{ 
  6.     Resp hander(req){ 
  7.       return handlerTempPlate(req); 
  8.     } 
  9.     //公司A是走代理的 
  10.     boolean isRequestByProxy(){ 
  11.        return true; 
  12.     } 
  13.     CompanyEnum getCompanyEnum(){ 
  14.      return CompanyEnum.A; 
  15.     }  
  16.      
  17. CompanyBServiceImpl extends AbstractCompanyCommonService{ 
  18.     Resp hander(req){ 
  19.       return handlerTempPlate(req); 
  20.     } 
  21.     //公司B是不走代理的 
  22.     boolean isRequestByProxy(){ 
  23.        return false; 
  24.     } 
  25.     CompanyEnum getCompanyEnum(){ 
  26.      return CompanyEnum.B; 
  27.     }  

來來來,工廠方法模式出爐咯:

 
 
 
 
  1. @Component 
  2. public class CompanyServiceFactory implements ApplicationContextAware { 
  3.  
  4.     private static Map map = new HashMap<>(); 
  5.  
  6.     @Override 
  7.     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 
  8.         Map tempMap = applicationContext.getBeansOfType(ICompanyCommonService.class); 
  9.         tempMap.values().forEach(iCompanyCommonService -> 
  10.                 map.put(iCompanyCommonService.getCompanyEnum(), iCompanyCommonService)); 
  11.     } 
  12.  
  13.     public Resp handler(req) { 
  14.         return map.get(CompanyEnum.getCompanyEnum(req.getCompanyFlag()).hander(req); 
  15.     } 

最后建議

最后,不要為了使用設(shè)計(jì)模式生搬硬套,而是優(yōu)化代碼過程中,發(fā)現(xiàn)這個(gè)設(shè)計(jì)模式剛好適用,才去用的哈。附上最后的代碼咯:

 
 
 
 
  1. @Service 
  2. public class CompanyHandler implements RequestHandler  { 
  3.    @Autowire 
  4.    private CompanyServiceFactory companyServiceFactory; 
  5.     
  6.    Resp hander(req){ 
  7.     return companyServiceFactory.handler(req); 
  8.   } 

本文轉(zhuǎn)載自微信公眾號(hào)「撿田螺的小男孩」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系撿田螺的小男孩公眾號(hào)。


分享名稱:一次代碼優(yōu)化實(shí)踐,用了模板方法+策略+工廠方法模式
網(wǎng)站路徑:http://m.5511xx.com/article/cdjgjcs.html