職責鏈模式

一、職責鏈模式異同

職責鏈模式類似於責任分配,可以讓多個對象共同參與完成某個任務,但同時也可以保證每個對象只承擔自己的任務。與常見的if…else if…else語句相比,職責鏈模式更加靈活、可擴展,並且可以方便地對代碼進行重構。

職責鏈模式的主要特點是將對象組織成一條鏈,並依次傳遞請求,每個對象負責處理自己能夠處理的請求,如果無法處理,則將請求傳遞給下一個對象處理,直至請求被處理完畢或者沒有對象可以處理為止。這種傳遞請求的方式就像一條鏈子,因此得名「職責鏈模式」。

與策略模式的區別在於:職責鏈模式強調的是對象之間的一種職責分配關係,而策略模式則強調對同一種問題採用不同的解決策略。因此,職責鏈模式更加適用於對象之間的消息傳遞與處理場景,而策略模式更加適用於演算法模塊的替換與自定義場景。

二、職責鏈模式的定義

職責鏈模式定義了一種消息傳遞機制,將多個消息處理對象組成一條鏈,依次發送消息並處理消息,達到請求者和處理者解耦的目的。職責鏈模式中通常包含以下角色:

  • 抽象處理者(Handler):定義處理請求的介面,同時持有下一個處理者的引用。
  • 具體處理者(ConcreteHandler):實現抽象處理者定義的介面,處理自己能夠處理的請求,如果無法處理,則將請求轉發給下一個處理者。
  • 客戶端(Client):創建並組裝請求鏈的角色。

三、職責鏈模式代碼示例

// 抽象處理者
abstract class Handler {
  protected Handler nextHandler;

  public void setNextHandler(Handler handler) {
    this.nextHandler = handler;
  }

  public abstract void handleRequest(int request);
}

// 具體處理者A
class ConcretHandlerA extends Handler {
  public void handleRequest(int request) {
    if (request >= 0 && request = 10 && request = 20 && request < 30) {
      System.out.println(this.getClass().getSimpleName() + " 處理請求 " + request);
    } else if (nextHandler != null) {
      nextHandler.handleRequest(request);
    }
  }
}

// 客戶端
public class Client {
  public static void main(String[] args) {
    Handler handlerA = new ConcretHandlerA();
    Handler handlerB = new ConcretHandlerB();
    Handler handlerC = new ConcretHandlerC();
    handlerA.setNextHandler(handlerB);
    handlerB.setNextHandler(handlerC);

    // 處理請求
    handlerA.handleRequest(5);
    handlerA.handleRequest(15);
    handlerA.handleRequest(25);
  }
}

四、職責鏈模式實例

某醫院的門診醫生根據病人的病情判斷應該給予何種治療,如果是一般常見病則只需要開些簡單的藥物治療即可,如果是嚴重疾病則需要轉介至專科醫生進行診治。在這種情況下,門診醫生可以構建職責鏈對病人的病情進行判斷,並將病人轉介至相應的醫生進行診治,從而降低醫生的工作負擔並提高病人的醫療質量。

五、職責鏈模式圖片

職責鏈模式的結構就像一條鏈子,其中每個對象都持有下一個對象的引用,用於將請求傳遞給下一個對象處理。

六、職責鏈模式優缺點

職責鏈模式的優點:

  • 解耦請求發送者和接收者,降低對象之間的耦合度。
  • 職責鏈可以動態地組合,方便用戶自由組合職責鏈。
  • 可以對請求的處理順序進行靈活配置,增加新的處理者也非常方便。

職責鏈模式的缺點:

  • 請求的發起者不能確定哪個對象最終處理了請求,需要等到運行時才能確定。
  • 如果職責鏈過長或者職責鏈設計不合理,可能會導致系統性能下降。

七、職責鏈模式類圖

職責鏈模式的類圖,其中抽象處理者定義了處理請求的介面,具體處理者實現了該介面並處理請求,客戶端則創建並組裝了請求處理鏈。

八、職責鏈模式結構圖

職責鏈模式的結構圖,其中每個對象都持有下一個對象的引用,用於將請求傳遞給下一個對象處理。

九、職責鏈模式實例採購單

某公司的採購員根據採購單的金額決定自己是否有許可權批准該採購單。小於等於1000元則直接批准,如果大於1000元且小於等於5000元則需要經過部門經理審批,如果大於5000元則還需要經過總經理的審批。

// 抽象處理者
abstract class Approver {
  protected Approver successor; //後繼處理對象
  protected String name; //審批者姓名

  public Approver(String name) {
    this.name = name;
  }

  //設置後繼者
  public void setSuccessor(Approver successor) {
    this.successor = successor;
  }

  //抽象請求處理方法
  public abstract void processRequest(PurchaseRequest request);
}

//具體處理者:主任類
class Director extends Approver {
  public Director(String name) {
    super(name);
  }

  public void processRequest(PurchaseRequest request) {
    if (request.getMoney() <= 10000) {
      System.out.println("主任 " + name + "審批採購單,金額為 " + request.getMoney() + " 元");
    } else {
      successor.processRequest(request); //轉發請求
    }
  }
}

//具體處理者:副董事長類
class VicePresident extends Approver {
  public VicePresident(String name) {
    super(name);
  }

  public void processRequest(PurchaseRequest request) {
    if (request.getMoney() <= 25000) {
      System.out.println("副董事長 " + name + "審批採購單,金額為 " + request.getMoney() + " 元");
    } else {
      successor.processRequest(request); //轉發請求
    }
  }
}

//具體處理者:董事長類
class President extends Approver {
  public President(String name) {
    super(name);
  }

  public void processRequest(PurchaseRequest request) {
    if (request.getMoney() <= 50000) {
      System.out.println("董事長 " + name + "審批採購單,金額為 " + request.getMoney() + " 元");
    } else {
      System.out.println("採購單金額太大," + name + "無法處理!");
    }
  }
}

//採購單類
class PurchaseRequest {
  private int money; //採購金額

  public PurchaseRequest(int money) {
    this.money = money;
  }

  public int getMoney() {
    return money;
  }

  public void setMoney(int money) {
    this.money = money;
  }
}

//客戶端代碼
public class Client {
  public static void main(String[] args) {
    // 先要組裝責任鏈
    Approver director = new Director("張三");
    Approver vp = new VicePresident("李四");
    Approver president = new President("王五");
    director.setSuccessor(vp);
    vp.setSuccessor(president);

    // 開始測試
    PurchaseRequest request1 = new PurchaseRequest(5000);
    director.processRequest(request1);

    PurchaseRequest request2 = new PurchaseRequest(10000);
    director.processRequest(request2);

    PurchaseRequest request3 = new PurchaseRequest(30000);
    director.processRequest(request3);

    PurchaseRequest request4 = new PurchaseRequest(100000);
    director.processRequest(request4);
  }
}

十、職責鏈模式實驗目的

  • 學習常用的設計模式之一——職責鏈模式。
  • 掌握職責鏈模式的定義、應用場景、基本結構、優缺點、類圖和實現方法。
  • 通過實際代碼實現,進一步理解職責鏈模式的設計思路和使用方法。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/240861.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 12:24
下一篇 2024-12-12 12:24

相關推薦

  • 手機安全模式怎麼解除?

    安全模式是一種手機自身的保護模式,它會禁用第三方應用程序並使用僅限基本系統功能。但有時候,安全模式會使你無法使用手機上的一些重要功能。如果你想解除手機安全模式,可以嘗試以下方法: …

    編程 2025-04-28
  • Qt State Machine與狀態機模式

    本文將介紹Qt State Machine和狀態機模式在Qt中的實現。Qt提供了QStateMachine和QState兩個類,可以方便地實現狀態機模式,並且能有效地處理複雜的、多…

    編程 2025-04-27
  • 顯示C++設計模式

    本文將詳細介紹顯示C++設計模式的概念、類型、優點和代碼實現。 一、概念 C++設計模式是在軟體設計階段定義,用於處理常見問題的可重用解決方案。這些解決方案是經過測試和驗證的,並已…

    編程 2025-04-27
  • Centos7進入單用戶模式的解釋

    本文將介紹如何在Centos7中進入單用戶模式,並從以下幾個方面進行詳細的闡述。 一、Centos7進入單用戶模式的解答 在Centos7中進入單用戶模式需要執行以下步驟: 1. …

    編程 2025-04-27
  • 深入解析PSM模式

    一、PSM模式是什麼 PSM模式,即頁面-狀態-模型模式,是一種前端開發模式。它以頁面為中心,將頁面內的所有狀態和業務邏輯抽象成一個由頁面轉化而來的虛擬狀態機模型,從而將業務邏輯與…

    編程 2025-04-25
  • 授權碼模式與OAuth2.0

    一、什麼是授權碼模式 授權碼模式(Authorization Code Grant Type)是OAuth2.0協議中最常用的授權方式之一,也是最為安全的一種授權方式。授權碼模式的…

    編程 2025-04-24
  • 谷歌瀏覽器深色模式

    一、深色模式的概念 深色模式是一種日益流行的 UI 設計趨勢,通過使用暗灰色或黑色背景,大大降低了屏幕的亮度,更加舒適和護眼。深色模式也被稱為暗黑模式。 谷歌瀏覽器深色模式的推出可…

    編程 2025-04-24
  • 暗黑模式的盛行

    一、背景和定義 暗黑模式起源於智能手錶和夜視儀等專業設備上的配色方案,是指採用黑底白字、暗灰底白字等相對較暗的背景色搭配亮色前景,以減少屏幕對用戶眼睛的刺激,降低視覺疲勞感。這種設…

    編程 2025-04-24
  • 從多個方面詳細闡述MVC模式和三層架構

    一、MVC模式 MVC是Model-View-Controller的縮寫,是一種應用於軟體工程的設計模式。MVC模式將一個軟體應用分為三個基本部分:模型(Model)、視圖(Vie…

    編程 2025-04-24
  • 單例模式的作用

    一、概念解釋 1、單例模式是指一個類只允許存在一個實例對象,且該對象能被系統中其他模塊所共用。該模式主要解決了全局變數的問題,在同一時間只有一個實例被使用,避免了多次重複實例化造成…

    編程 2025-04-23

發表回復

登錄後才能評論