在實際開發中,咱們經常會出現如下的代碼狀況:java
if (state == 1){ haveBreakfast(); } else if (state == 2){ haveLunch(); } else if (state == 3){ haveDinner(); }
這種代碼結構是否是很糟糕,若是將來又有一個新狀態加入,則又要加入一個新的else if語句,如此往復,則會產生一個很是糟糕的代碼結構體。設計模式
那麼該如何優化這串代碼呢?這裏有兩種方式:一種是使用責任鏈模式,一種是使用策略模式。優化
咱們先來看看責任鏈模式是如何優化這串代碼的:this
首先上UML類圖:spa
設計代碼:設計
public abstract class Handler { private Handler nextHandler; private int state; public Handler(int state) { this.state = state; } // 處理請求傳遞,注意final,子類不可重寫 public final void handleMessage(int state) { // 傳遞狀態是否符合,不符合走下一級 if (this.state == state) { this.report(); } else { if (this.nextHandler != null) { // 交給下級處理 this.nextHandler.handleMessage(demand); } else { System.out.println("沒有下級可處理"); } } } public void setNextHandler(Handler handler) { this.nextHandler = handler; } // 抽象方法,子類實現 // 這裏也用了模板方法設計模式 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("我在吃晚餐"); } }
主類實現:code
public class Client { public static void main(String[] args) { // 初始化 HaveBreakfast breakfast = new HaveBreakfast(); HaveLunch lunch = new HaveLunch(); HaveDinner dinner = new HaveDinner(); // 設置下一級 lunch.setNextHandler(dinner); breakfast.setNextHandler(lunch); // 我要吃中餐 int lunchState = 2; breakfast.report(lunchState); // 我要吃晚餐 int dinnerState = 3; breakfast.report(dinnerState); } }
用責任鏈模式實現了代碼的解耦,之後只要根據state值的不一樣,調用breakfast.report(state)便可。繼承
一樣上UML類圖:圖片
設計代碼:開發
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 Map<Integer, Strategy> map = 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(); } }
實現代碼:
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(); } }
用策略模式也一樣實現了代碼的解耦。
經過以上分析,咱們知道使用責任鏈模式和策略模式都能解耦雜亂的if-else代碼,但二者又有什麼不一樣,實際開發中咱們該選用那種?結論是責任鏈是一種鏈式結構的處理方式,是有層級性的,而策略模式並無層級關係,選用哪一種可根據開發需求進行定奪。
回頭看看上面責任鏈模式的代碼,Handler抽象類中定義了幾個方法,一個是final修飾的handleMessage,一個是抽象方法report,還有一個是setNextHandler。這三個分別對應模板方法模式中的三個基本方法,分別是具體方法handleMessage(抽象類聲明並實現,子類不實現)、抽象方法report(抽象類聲明,子類必須實現)、鉤子方法setNextHandler(抽象類聲明並實現,子類可擴展)。這樣結合模板方法模式的好處在哪?首先加了handleMessage方法,把請求的傳遞判斷從子類中剝離出來,讓子類在report方法中專心處理請求的業務邏輯,作到了單一職責原則。子類的實現只要繼承該抽象類便可,很是簡單。