」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 瞭解後端開發中的責任鏈設計模式

瞭解後端開發中的責任鏈設計模式

發佈於2024-11-08
瀏覽:658

Understanding the Chain of Responsibility Design Pattern in Backend Development

责任链 (CoR) 设计模式是一种强大的行为模式,可以显着增强后端开发。此模式允许您通过处理程序链传递请求,其中每个处理程序可以处理请求或将其传递到下一个处理程序。在本博客中,我们将从后端角度探讨 CoR 模式,特别关注其在 Web 服务中的请求验证和处理中的应用,并使用 Java 作为示例。

何时使用责任链模式

责任链模式在后端系统中特别有用,其中请求可能需要多个验证和处理步骤才能最终确定。例如,在 RESTful API 中,传入请求在由主要业务逻辑处理之前可能需要验证身份验证、授权和数据完整性。这些问题中的每一个都可以由链中的不同处理程序来处理,从而允许明确分离职责和模块化代码。这种模式在中间件架构中也很有用,其中不同的中间件组件可以处理请求,从而实现基于特定标准的灵活处理。

责任链模式的结构

CoR 模式由三个关键组件组成:处理程序、具体处理程序和客户端。 Handler 定义处理请求的接口并维护对链中下一个处理程序的引用。每个具体处理程序实现特定类型请求处理的逻辑,决定是处理请求还是将其传递给下一个处理程序。 Client 将请求发送到处理程序链,但不知道哪个处理程序将最终处理该请求。这种解耦提高了后端系统的可维护性和灵活性。

Java 实现示例

第 1 步:定义处理程序接口

首先,我们将定义一个 RequestHandler 接口,其中包含设置下一个处理程序和处理请求的方法:

abstract class RequestHandler {
    protected RequestHandler nextHandler;

    public void setNext(RequestHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    public void handleRequest(Request request) {
        if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}

第 2 步:创建具体处理程序

接下来,我们将创建扩展 RequestHandler 类的具体处理程序类,每个处理程序类负责请求处理的特定方面:

class AuthenticationHandler extends RequestHandler {
    @Override
    public void handleRequest(Request request) {
        if (request.isAuthenticated()) {
            System.out.println("Authentication successful.");
            super.handleRequest(request);
        } else {
            System.out.println("Authentication failed.");
            request.setValid(false);
        }
    }
}

class AuthorizationHandler extends RequestHandler {
    @Override
    public void handleRequest(Request request) {
        if (request.isAuthorized()) {
            System.out.println("Authorization successful.");
            super.handleRequest(request);
        } else {
            System.out.println("Authorization failed.");
            request.setValid(false);
        }
    }
}

class DataValidationHandler extends RequestHandler {
    @Override
    public void handleRequest(Request request) {
        if (request.isDataValid()) {
            System.out.println("Data validation successful.");
            super.handleRequest(request);
        } else {
            System.out.println("Data validation failed.");
            request.setValid(false);
        }
    }
}

class BusinessLogicHandler extends RequestHandler {
    @Override
    public void handleRequest(Request request) {
        if (request.isValid()) {
            System.out.println("Processing business logic...");
            // Perform the main business logic here
        } else {
            System.out.println("Request is invalid. Cannot process business logic.");
        }
    }
}

第 3 步:设置链条

现在,我们将根据其职责设置处理程序链:

public class RequestProcessor {
    private RequestHandler chain;

    public RequestProcessor() {
        // Create handlers
        RequestHandler authHandler = new AuthenticationHandler();
        RequestHandler authzHandler = new AuthorizationHandler();
        RequestHandler validationHandler = new DataValidationHandler();
        RequestHandler logicHandler = new BusinessLogicHandler();

        // Set up the chain
        authHandler.setNext(authzHandler);
        authzHandler.setNext(validationHandler);
        validationHandler.setNext(logicHandler);

        this.chain = authHandler; // Start of the chain
    }

    public void processRequest(Request request) {
        chain.handleRequest(request);
    }
}

第四步:客户端代码

以下是客户端代码与请求处理链交互的方式:

public class Main {
    public static void main(String[] args) {
        RequestProcessor processor = new RequestProcessor();

        // Simulating a valid request
        Request validRequest = new Request(true, true, true);
        processor.processRequest(validRequest);

        // Simulating an invalid request
        Request invalidRequest = new Request(true, false, true);
        processor.processRequest(invalidRequest);
    }
}

支援班

这是一个简单的Request类,将用于封装请求数据:

class Request {
    private boolean authenticated;
    private boolean authorized;
    private boolean dataValid;
    private boolean valid = true;

    public Request(boolean authenticated, boolean authorized, boolean dataValid) {
        this.authenticated = authenticated;
        this.authorized = authorized;
        this.dataValid = dataValid;
    }

    public boolean isAuthenticated() {
        return authenticated;
    }

    public boolean isAuthorized() {
        return authorized;
    }

    public boolean isDataValid() {
        return dataValid;
    }

    public boolean isValid() {
        return valid;
    }

    public void setValid(boolean valid) {
        this.valid = valid;
    }
}

输出说明

当您运行客户端代码时,您将观察到以下输出:

Authentication successful.
Authorization successful.
Data validation successful.
Processing business logic...
Authentication successful.
Authorization failed.
Request is invalid. Cannot process business logic.
  • 第一个请求已通过所有处理程序成功处理,证明整个链按预期工作。
  • 第二个请求在授权步骤期间失败,停止进一步处理并防止无效请求到达业务逻辑。

责任链模式的好处

  1. 关注点分离:每个处理程序都有不同的职责,使代码更易于理解和维护。这种分离使团队能够专注于请求处理的特定方面,而不必担心整个工作流程。

  2. 灵活的请求处理:可以在不改变现有逻辑的情况下添加或删除处理程序,从而可以轻松适应新的需求或业务规则的变化。这种模块化支持敏捷开发实践。

  3. 提高可维护性:处理程序的解耦性质意味着一个处理程序中的更改(例如更新验证逻辑)不会影响其他处理程序,从而最大限度地降低了将错误引入系统的风险。

  4. 更轻松的测试:可以单独测试各个处理程序,从而简化测试过程。这允许有针对性的单元测试和更直接地调试特定请求处理步骤。

缺点

  1. 性能开销:长链处理程序可能会引入延迟,特别是在需要按顺序执行许多检查的情况下。在性能关键型应用程序中,这可能会成为一个问题。

  2. 流程控制的复杂性:虽然该模式简化了各个处理程序的职责,但它可能会使请求处理的整体流程变得复杂。了解如何通过多个处理程序处理请求可能需要新团队成员提供额外的文档和工作。

结论

责任链模式是后端开发中的一种有效设计模式,它通过促进关注点分离、灵活性和可维护性来增强请求处理。通过实现这种请求验证和处理模式,开发人员可以创建能够有效处理各种需求的强大且可扩展的系统。无论是在 RESTful API、中间件处理还是其他后端应用程序中,采用 CoR 模式都可以带来更简洁的代码和改进的架构设计,最终产生更可靠和可维护的软件解决方案。

版本聲明 本文轉載於:https://dev.to/syridit118/understanding-the-chain-of-responsibility-design-pattern-in-backend-development-p2f?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 使用純 Javascript 只需幾行即可實現飛向購物車的動畫。
    使用純 Javascript 只需幾行即可實現飛向購物車的動畫。
    最近,我偶然發現了一個舊教程,展示了使用 jQuery 實現飛行到購物車的動畫。我想透過使用純 JavaScript 實現相同的效果來挑戰自己。 我創建了一個包含產品和購物車圖示的簡單佈局。樣式並不重要,所以我們不會在這裡討論它。 訣竅是複製產品圖像,將其添加到產品元素之前。然後計算克隆圖像和購...
    程式設計 發佈於2024-11-08
  • Bokeh 是一個有趣的 Python 資料視覺化資料工具
    Bokeh 是一個有趣的 Python 資料視覺化資料工具
    資料視覺化在解釋大量資訊方面發揮關鍵作用。 Bokeh 等工具已成為建立互動式儀表板和報告的流行解決方案。每個工具都具有獨特的優勢,具體取決於您專案的複雜性和您首選的程式語言。在本文中,我們將深入研究每個工具,然後專注於 Bokeh,包括實踐範例和雲端中的部署。 以便... 什麼是散景? Bok...
    程式設計 發佈於2024-11-08
  • django-components v 模板現在與 Vue 或 React 相當
    django-components v 模板現在與 Vue 或 React 相當
    嘿,我是 Juro,我是 django-components 的維護者之一。在 v0.90-0.94 版本中,我們添加了一些功能,使模板中的元件使用更加靈活,類似於 JSX / Vue。 (此資訊已經有點過時了(一個月前發布;最新的是v0.101),因為我正忙著添加對JS / CSS 變數、Typ...
    程式設計 發佈於2024-11-08
  • 如何在 Go 中解密 AES ECB 模式加密?
    如何在 Go 中解密 AES ECB 模式加密?
    Go 中的AES ECB 加密Go 中的AES ECB 加密package main import ( "crypto/aes" "fmt" ) func decryptAes128Ecb(data, key []byte) []byte { ...
    程式設計 發佈於2024-11-08
  • 在 GitHub-echo 中實現 TOML 配置支持
    在 GitHub-echo 中實現 TOML 配置支持
    介绍 最近,我有机会通过添加对 TOML 配置文件的支持来增强 github-echo 命令行工具。此功能允许用户在 .github-echo-config.toml 文件中设置持久默认选项,从而减少每次使用该工具时手动输入重复配置的需要。在这篇文章中,我将向您介绍我在该功能上的经...
    程式設計 發佈於2024-11-08
  • 如何使用 SimpleXML 和 DOMDocument 刪除 XPath 節點?
    如何使用 SimpleXML 和 DOMDocument 刪除 XPath 節點?
    SimpleXML:刪除XPath 節點在本文中,我們將探討如何使用以下方法有效地從XML 文件中刪除父節點: SimpleXML 和XPath。 了解 SimpleXML限制提供的程式碼嘗試使用 SimpleXML 在透過 XPath 找到父節點後刪除它。然而,SimpleXML 的 unset(...
    程式設計 發佈於2024-11-08
  • 建立一個 React Hook 以任意角度旋轉影像
    建立一個 React Hook 以任意角度旋轉影像
    在Web開發中,您可能需要旋轉影像,這在CSS中很容易做到。像這樣的簡單程式碼變換:rotate(90deg);。但是如果我們想用 JS 來做呢? TLDR 將圖像繪製到瀏覽器環境中的畫布上並旋轉它。但在此之前,我們需要做一些數學運算來保持原始影像的長寬比。 核 ...
    程式設計 發佈於2024-11-08
  • Lithe 中間件:它是如何運作的以及如何創建自己的中間件
    Lithe 中間件:它是如何運作的以及如何創建自己的中間件
    中间件提供了一种方便的机制来检查和过滤进入应用程序的 HTTP 请求。 例如,Lithe 包含检查用户是否经过身份验证的中间件。如果没有,中间件会将用户重定向到登录屏幕。如果用户通过身份验证,中间件将允许请求继续。 中间件如何在 Lithe 中工作 在 Lithe 中,中间件是能够访...
    程式設計 發佈於2024-11-08
  • 如何在 JavaScript 中建立具有重複元素的陣列?
    如何在 JavaScript 中建立具有重複元素的陣列?
    JavaScript 中重複元素的數組創建具有多次重複的相同元素的數組在各種編程場景中至關重要。在 Python 中,這可以透過列表乘法來實現,如 [2] * 5 所示。但是,此功能在 JavaScript 陣列中不能直接使用。 自訂函數方法為了滿足這種需求,一種方法是建立自訂函數,例如問題中提供的...
    程式設計 發佈於2024-11-08
  • ## MySQL 中的 LIKE 與 LOCATE:哪個運算子是效能之王?
    ## MySQL 中的 LIKE 與 LOCATE:哪個運算子是效能之王?
    MySQL LIKE 與LOCATE 效能比較在MySQL 中查找資料時,你可能會想知道LIKE 和LOCATE 哪個運算子效率更高?本文探討了這兩個運算子之間的效能差異。 在典型的使用場景中,LIKE 比 LOCATE 稍快。這主要是因為 LIKE 不像 LOCATE 那樣執行與 0 的額外比較。...
    程式設計 發佈於2024-11-08
  • 如何使用 PHP 更新多個 MySQL 行的表單資料?
    如何使用 PHP 更新多個 MySQL 行的表單資料?
    使用表單資料更新多個MySQL 行在Web 開發中,通常有一個表單,使用者可以在其中編輯資料庫中的記錄。常見的情況是使用修改後的資料更新同一個表中的多行。這可以使用 PHP 和 MySQL 來實作。 表單結構與資料擷取初始表單負責呈現要編輯的資料。在此範例中,表單從資料庫中擷取具有特定 GALLER...
    程式設計 發佈於2024-11-08
  • 為什麼我不能在 Go 中將 []byte 分配給字串?
    為什麼我不能在 Go 中將 []byte 分配給字串?
    了解位元組分配錯誤:無法將[]byte 指派給字串在嘗試讀取資料夾中的檔案時,遇到了錯誤嘗試讀取檔案內容時,「無法在多重賦值中將[]byte 指派給z(字串類型)」。讓我們深入研究這個錯誤背後的原因。 理解多重賦值當在一行中為多個變數賦值時,如程式碼所示:z, err := ioutil.ReadF...
    程式設計 發佈於2024-11-08
  • 如何使用 React 和 Typescript 建立自訂表格元件(第 2 部分)
    如何使用 React 和 Typescript 建立自訂表格元件(第 2 部分)
    介绍 耶! ?您已经完成了这个由两部分组成的系列的最后一部分!如果您还没有查看第 1 部分,请先停在此处并完成第 1 部分。别担心,我们会等你回来! ? 在第 1 部分中,我们构建了 CustomTable 组件。您可以在这里看到它的实际效果。 在第二部分中,我们将扩展该组件以添加...
    程式設計 發佈於2024-11-08
  • 使用 TypeScript 和 ioredis 在 Node.js 中建立高效能快取管理器
    使用 TypeScript 和 ioredis 在 Node.js 中建立高效能快取管理器
    使用基於 ioredis 建構的多功能、易於使用的快取管理器來提升 Node.js 應用程式的效能。簡化快取、優化效率並簡化操作。 我根據自己的需求開發了一個基於 ioredis 的類,重點關注易用性和性能。它包括 TypeScript 支持,旨在實現簡單使用和高效操作。它仍然可以進一步改進和優化...
    程式設計 發佈於2024-11-08
  • 超類別引用和子類別對象
    超類別引用和子類別對象
    Java 是一種強型別語言。 標準轉換和自動升級適用於原始型別。 嚴格執行型別相容性。 通常,一個類別的引用變數不能引用另一個類別的物件。 即使類別 X 和 Y 在結構上相同,也不可能將 X 的引用分配給 Y 的對象,因為類型不同。 一般來說,物件引用變數只能引用其類型的物件。 型別強...
    程式設計 發佈於2024-11-08

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3