摘要:拓展模板方法模式回頭看看上面責(zé)任鏈模式的代碼,抽象類中定義了幾個(gè)方法,一個(gè)是修飾的,一個(gè)是抽象方法,還有一個(gè)是。
前情提要
在實(shí)際開(kāi)發(fā)中,我們常常會(huì)出現(xiàn)以下的代碼情況:
if (state == 1){ haveBreakfast(); } else if (state == 2){ haveLunch(); } else if (state == 3){ haveDinner(); }
這種代碼結(jié)構(gòu)是不是很糟糕,如果未來(lái)又有一個(gè)新?tīng)顟B(tài)加入,則又要加入一個(gè)新的else if語(yǔ)句,如此往復(fù),則會(huì)產(chǎn)生一個(gè)非常糟糕的代碼結(jié)構(gòu)體。
那么該如何優(yōu)化這串代碼呢?這里有兩種方式:一種是使用責(zé)任鏈模式,一種是使用策略模式。
我們先來(lái)看看責(zé)任鏈模式是如何優(yōu)化這串代碼的:
責(zé)任鏈模式首先上UML類圖:
設(shè)計(jì)代碼:
public abstract class Handler { private Handler nextHandler; private int state; public Handler(int state) { this.state = state; } // 處理請(qǐng)求傳遞,注意final,子類不可重寫(xiě) public final void handleMessage(int state) { // 傳遞狀態(tài)是否符合,不符合走下一級(jí) if (this.state == state) { this.report(); } else { if (this.nextHandler != null) { // 交給下級(jí)處理 this.nextHandler.handleMessage(demand); } else { System.out.println("沒(méi)有下級(jí)可處理"); } } } public void setNextHandler(Handler handler) { this.nextHandler = handler; } // 抽象方法,子類實(shí)現(xiàn) // 這里也用了模板方法設(shè)計(jì)模式 public abstract void report(); } public class HaveBreakfast extends Hanlder { public HaveBreakfast(){ super(1); } public void report(){ System.out.println("我在吃早餐"); } } public class HaveLunch extends Hanlder { public HaveLunch(){ super(2); } public void report(){ System.out.println("我在吃中餐"); } } public class HaveDinner extends Hanlder { public HaveDinner(){ super(3); } public void report(){ System.out.println("我在吃晚餐"); } }
主類實(shí)現(xiàn):
public class Client { public static void main(String[] args) { // 初始化 HaveBreakfast breakfast = new HaveBreakfast(); HaveLunch lunch = new HaveLunch(); HaveDinner dinner = new HaveDinner(); // 設(shè)置下一級(jí) lunch.setNextHandler(dinner); breakfast.setNextHandler(lunch); // 我要吃中餐 int lunchState = 2; breakfast.report(lunchState); // 我要吃晚餐 int dinnerState = 3; breakfast.report(dinnerState); } }
用責(zé)任鏈模式實(shí)現(xiàn)了代碼的解耦,以后只要根據(jù)state值的不同,調(diào)用breakfast.report(state)即可。
策略模式同樣上UML類圖:
設(shè)計(jì)代碼:
public interface Strategy { public void algorithm(); } public class HaveBreakfast implements Strategy{ public void algorithm() { System.out.println("我在吃早餐"); } } public class HaveLunch implements Strategy{ public void algorithm() { System.out.println("我在吃中餐"); } } public class HaveDinner implements Strategy{ public void algorithm() { System.out.println("我在吃晚餐"); } } public class Context implements Strategy{ private Strategy strategy; private final Mapmap = new HashMap<>(); public void setStrategy(int state) { initMap(); this.Strategy = this.map.get(state); } private void initMap() { this.map.put(1, new HaveBreakfast()); this.map.put(2, new HaveLunch()); this.map.put(3, new HaveDinner()); } public void algorithm() { this.strategy.algorithm(); } }
實(shí)現(xiàn)代碼:
public class Client { public static void main(String[] args) { Context context = new Context(); // 我要吃中餐 int lunchState = 2; context.setStrategy(lunchState); context.algorithm(); // 我要吃晚餐 int dinnerState = 3; context.setStrategy(dinnerState); context.algorithm(); } }
用策略模式也同樣實(shí)現(xiàn)了代碼的解耦。
策略模式 VS 責(zé)任鏈模式通過(guò)以上分析,我們知道使用責(zé)任鏈模式和策略模式都能解耦雜亂的if-else代碼,但兩者又有什么不同,實(shí)際開(kāi)發(fā)中我們?cè)撨x用那種?結(jié)論是責(zé)任鏈?zhǔn)且环N鏈?zhǔn)浇Y(jié)構(gòu)的處理方式,是有層級(jí)性的,而策略模式并沒(méi)有層級(jí)關(guān)系,選用哪種可根據(jù)開(kāi)發(fā)需求進(jìn)行定奪。
拓展——模板方法模式回頭看看上面責(zé)任鏈模式的代碼,Handler抽象類中定義了幾個(gè)方法,一個(gè)是final修飾的handleMessage,一個(gè)是抽象方法report,還有一個(gè)是setNextHandler。這三個(gè)分別對(duì)應(yīng)模板方法模式中的三個(gè)基本方法,分別是具體方法handleMessage(抽象類聲明并實(shí)現(xiàn),子類不實(shí)現(xiàn))、抽象方法report(抽象類聲明,子類必須實(shí)現(xiàn))、鉤子方法setNextHandler(抽象類聲明并實(shí)現(xiàn),子類可擴(kuò)展)。
這樣結(jié)合模板方法模式的好處在哪?首先加了handleMessage方法,把請(qǐng)求的傳遞判斷從子類中剝離出來(lái),讓子類在report方法中專心處理請(qǐng)求的業(yè)務(wù)邏輯,做到了單一職責(zé)原則。子類的實(shí)現(xiàn)只要繼承該抽象類即可,非常簡(jiǎn)單。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/72603.html
摘要:大家好,我是冰河有句話叫做投資啥都不如投資自己的回報(bào)率高。馬上就十一國(guó)慶假期了,給小伙伴們分享下,從小白程序員到大廠高級(jí)技術(shù)專家我看過(guò)哪些技術(shù)類書(shū)籍。 大家好,我是...
摘要:實(shí)戰(zhàn)高并發(fā)程序設(shè)計(jì)這本書(shū)是目前點(diǎn)評(píng)推薦比較多的書(shū),其特色是案例小,好實(shí)踐代碼有場(chǎng)景,實(shí)用。想要學(xué)習(xí)多線程的朋友,這本書(shū)是我大力推薦的,我的個(gè)人博客里面二十多篇的多線程博文都是基于此書(shū),并且在這本書(shū)的基礎(chǔ)上進(jìn)行提煉和總結(jié)而寫(xiě)出來(lái)的。 學(xué)習(xí)的最好途徑就是看書(shū),這是我自己學(xué)習(xí)并且小有了一定的積累之后的第一體會(huì)。個(gè)人認(rèn)為看書(shū)有兩點(diǎn)好處:showImg(/img/bVr5S5); 1.能出版出...
學(xué)習(xí)JVM的相關(guān)資料 《深入理解Java虛擬機(jī)——JVM高級(jí)特性與最佳實(shí)踐(第2版)》 showImg(https://segmentfault.com/img/bVbsqF5?w=200&h=200); 基于最新JDK1.7,圍繞內(nèi)存管理、執(zhí)行子系統(tǒng)、程序編譯與優(yōu)化、高效并發(fā)等核心主題對(duì)JVM進(jìn)行全面而深入的分析,深刻揭示JVM的工作原理。以實(shí)踐為導(dǎo)向,通過(guò)大量與實(shí)際生產(chǎn)環(huán)境相結(jié)合的案例展示了解...
閱讀 714·2021-11-25 09:43
閱讀 2984·2021-11-24 10:20
閱讀 1050·2021-10-27 14:18
閱讀 1106·2021-09-08 09:36
閱讀 3423·2021-07-29 14:49
閱讀 1813·2019-08-30 14:07
閱讀 2965·2019-08-29 16:52
閱讀 3075·2019-08-29 13:12