十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶(hù) + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專(zhuān)業(yè)推廣+無(wú)憂(yōu)售后,網(wǎng)站問(wèn)題一站解決
這篇文章主要講解了“怎么用模板方法+策略+工廠方法模式來(lái)優(yōu)化代碼”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“怎么用模板方法+策略+工廠方法模式來(lái)優(yōu)化代碼”吧!
為襄陽(yáng)等地區(qū)用戶(hù)提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及襄陽(yáng)網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為做網(wǎng)站、成都網(wǎng)站制作、襄陽(yáng)網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專(zhuān)業(yè)、用心的態(tài)度為用戶(hù)提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶(hù)的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!
優(yōu)化代碼前
先來(lái)了解一下類(lèi)似的業(yè)務(wù)場(chǎng)景,簡(jiǎn)言之,就是:多個(gè)商戶(hù)接入我們系統(tǒng),都是走一個(gè)類(lèi)似的流程通過(guò)http請(qǐng)求出去的。

優(yōu)化前,每個(gè)公司對(duì)應(yīng)一個(gè)句柄服務(wù),偽代碼如下:
// 商戶(hù)A處理句柄 CompanyAHandler implements RequestHandler { Resp hander(req){ //查詢(xún)商戶(hù)信息 queryMerchantInfo(); //加簽 signature(); // http請(qǐng)求(走代理) httpRequestbyProxy() // 驗(yàn)簽 verify(); } } // 商戶(hù)B處理句柄 CompanyBHandler implements RequestHandler { Resp hander(Rreq){ //查詢(xún)商戶(hù)信息 queryMerchantInfo(); //加簽 signature(); // http請(qǐng)求(不走代理) httpRequestbyDirect(); // 驗(yàn)簽 verify(); } } // 商戶(hù)C處理句柄 CompanyBHandler implements RequestHandler { Resp hander(Rreq){ //查詢(xún)商戶(hù)信息 queryMerchantInfo(); // webservice 方式調(diào)用 requestByWebservice(); } }優(yōu)化代碼思路
我的優(yōu)化代碼思路,是有「重復(fù)代碼,先把它抽出來(lái),或者公用變量,或者公用方法,伸著公用類(lèi)」。所以呢,查詢(xún)商戶(hù)信息呀,加簽呀,http請(qǐng)求呀先全部各抽成一個(gè)公用方法。你細(xì)心點(diǎn)會(huì)發(fā)現(xiàn),連每個(gè)Handler處理過(guò)程都很類(lèi)似的,大概都是查詢(xún)商戶(hù)信息+加簽+http請(qǐng)求+驗(yàn)簽,于是呢,可以直接把它們抽象成一個(gè)公用類(lèi)呀~在這里就要引入模板方法模式咯
模板方法模式
在模板模式(Template Pattern)中,一個(gè)抽象類(lèi)公開(kāi)定義了執(zhí)行它的方法的方式/模板。它的子類(lèi)可以按需要重寫(xiě)方法實(shí)現(xiàn),但調(diào)用將以抽象類(lèi)中定義的方式進(jìn)行。 這種類(lèi)型的設(shè)計(jì)模式屬于行為型模式。
這種類(lèi)型的設(shè)計(jì)模式屬于行為型模式。
既然每個(gè)Handler處理,都是類(lèi)似的流程,那「定義一個(gè)抽象類(lèi),把查詢(xún)商戶(hù)信息,加簽,http請(qǐng)求,驗(yàn)簽什么的,都放到里面去,儼然一個(gè)模板一樣」。然后,因?yàn)橛行┥虘?hù)走h(yuǎn)ttp代理,有些又沒(méi)走代理,怎么辦呢? 定義「一個(gè)抽象方法,給子類(lèi)實(shí)現(xiàn)」嘛,因?yàn)槟芄灿镁头诺礁割?lèi)(當(dāng)前的抽象類(lèi)),不能共用就放到子類(lèi)嘛~代碼如下:
abstract class AbstractCompanyCommonService implements ICompanyCommonService { //模板方法 Resp handlerTempPlate(req){ //查詢(xún)商戶(hù)信息 queryMerchantInfo(); // 加簽 signature(); //http 請(qǐng)求 if(isRequestByProxy()){ httpProxy(); }else{ httpDirect(); } // 驗(yàn)簽 verifySinature(); } // Http是否走代理 abstract boolean isRequestByProxy(); }子類(lèi)商戶(hù)A實(shí)現(xiàn):
CompanyAServiceImpl extends AbstractCompanyCommonService{ Resp hander(req){ return handlerTempPlate(req); } //公司A是走代理的 boolean isRequestByProxy(){ return true; }子類(lèi)商戶(hù)B實(shí)現(xiàn):
CompanyBServiceImpl extends AbstractCompanyCommonService{ Resp hander(req){ return handlerTempPlate(req); } //公司B是不走代理的 boolean isRequestByProxy(){ return false; }策略模式
心細(xì)的讀者會(huì)發(fā)現(xiàn),甚至提出疑問(wèn),「你的商戶(hù)C的服務(wù)實(shí)現(xiàn)跟你定義的公用模板,不太一樣呢」,那當(dāng)然,實(shí)際開(kāi)發(fā)中,不跟你定義的模板一樣太常見(jiàn)了,需求是產(chǎn)品提的嘛,又不是根據(jù)你模板提的,是代碼服務(wù)于需求的。好了,不多說(shuō)啦,我使用了策略模式,來(lái)優(yōu)化這個(gè)問(wèn)題。
在策略模式(Strategy Pattern)中,一個(gè)類(lèi)的行為或其算法可以在運(yùn)行時(shí)更改。這種類(lèi)型的設(shè)計(jì)模式屬于行為型模式。
策略模式理解起來(lái)其好抽象對(duì)不對(duì)?我個(gè)人理解,其實(shí)策略模式就是定義一個(gè)方法(所謂算法),給子類(lèi)自己去實(shí)現(xiàn)。實(shí)際上就是「定義個(gè)方法/接口,讓子類(lèi)自己去實(shí)現(xiàn)」??创a吧:
// 定義一個(gè)方法,把策略交給子類(lèi)去實(shí)現(xiàn)。 interface ICompanyCommonService{ Resp hander(req); }前面商戶(hù)A和商戶(hù)B還是不變,使用抽象類(lèi)AbstractCompanyCommonService的模板,模板不滿(mǎn)足商戶(hù)C,商戶(hù)C只能自己去實(shí)現(xiàn)咯,各個(gè)子類(lèi)自己去實(shí)現(xiàn)的行為,就是策略模式的體現(xiàn)呢,如下:
CompanyCServiceImpl extends AbstractCompanyCommonService{ Res hander(req){ //查詢(xún)商戶(hù)信息 queryMerchantInfo(); requestByWebservice(); } //隨意了,你都不走模板了 boolean isRequestByProxy(){ return false; }工廠方法模式
商戶(hù)A、B、C服務(wù)怎么被管理呢,之前分別給A,B,C服務(wù)實(shí)現(xiàn)handler的,現(xiàn)在好了,都不知道怎么管理了,怎么知道調(diào)用哪個(gè)呢?別慌,解決方案是「工廠方法模式」。
在工廠模式中,我們?cè)趧?chuàng)建對(duì)象時(shí)不會(huì)對(duì)客戶(hù)端暴露創(chuàng)建邏輯,并且是通過(guò)使用一個(gè)共同的接口來(lái)指向新創(chuàng)建的對(duì)象。
工廠方法模式具體實(shí)現(xiàn)就是:接口定義一個(gè)枚舉,每個(gè)服務(wù)實(shí)現(xiàn)都重新實(shí)現(xiàn)枚舉,設(shè)置唯一標(biāo)志枚舉,再交給spring容器管理??创a咯:
interface ICompanyCommonService{ Resp hander(req); CompanyEnum getCompanyEnum(); } CompanyAServiceImpl extends AbstractCompanyCommonService{ Resp hander(req){ return handlerTempPlate(req); } //公司A是走代理的 boolean isRequestByProxy(){ return true; } CompanyEnum getCompanyEnum(){ return CompanyEnum.A; } CompanyBServiceImpl extends AbstractCompanyCommonService{ Resp hander(req){ return handlerTempPlate(req); } //公司B是不走代理的 boolean isRequestByProxy(){ return false; } CompanyEnum getCompanyEnum(){ return CompanyEnum.B; }來(lái)來(lái)來(lái),工廠方法模式出爐咯:
@Component public class CompanyServiceFactory implements ApplicationContextAware { private static Map map = new HashMap<>(); @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { Map tempMap = applicationContext.getBeansOfType(ICompanyCommonService.class); tempMap.values().forEach(iCompanyCommonService -> map.put(iCompanyCommonService.getCompanyEnum(), iCompanyCommonService)); } public Resp handler(req) { return map.get(CompanyEnum.getCompanyEnum(req.getCompanyFlag()).hander(req); } } 最后建議
最后,不要為了使用設(shè)計(jì)模式生搬硬套,而是優(yōu)化代碼過(guò)程中,發(fā)現(xiàn)這個(gè)設(shè)計(jì)模式剛好適用,才去用的哈。附上最后的代碼咯:
@Service public class CompanyHandler implements RequestHandler { @Autowire private CompanyServiceFactory companyServiceFactory; Resp hander(req){ return companyServiceFactory.handler(req); } }感謝各位的閱讀,以上就是“怎么用模板方法+策略+工廠方法模式來(lái)優(yōu)化代碼”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)怎么用模板方法+策略+工廠方法模式來(lái)優(yōu)化代碼這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!