„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Verständnis des Chain-of-Responsibility-Designmusters in der Backend-Entwicklung

Verständnis des Chain-of-Responsibility-Designmusters in der Backend-Entwicklung

Veröffentlicht am 08.11.2024
Durchsuche:907

Understanding the Chain of Responsibility Design Pattern in Backend Development

Das Designmuster Chain of Responsibility (CoR) ist ein leistungsstarkes Verhaltensmuster, das die Backend-Entwicklung erheblich verbessern kann. Mit diesem Muster können Sie Anfragen durch eine Kette von Handlern weiterleiten, wobei jeder Handler die Anfrage entweder verarbeiten oder an den nächsten Handler weiterleiten kann. In diesem Blog werden wir das CoR-Muster aus einer Backend-Perspektive untersuchen und uns dabei insbesondere auf seine Anwendung bei der Anforderungsvalidierung und -verarbeitung in einem Webdienst konzentrieren, wobei wir Java als Beispiele verwenden.

Wann sollte das Chain-of-Responsibility-Muster verwendet werden?

Das Chain of Responsibility-Muster ist besonders nützlich in Backend-Systemen, in denen Anfragen möglicherweise mehrere Validierungs- und Verarbeitungsschritte erfordern, bevor sie abgeschlossen werden können. Beispielsweise müssen in einer RESTful-API eingehende Anfragen möglicherweise auf Authentifizierung, Autorisierung und Datenintegrität validiert werden, bevor sie von der Hauptgeschäftslogik verarbeitet werden. Jedes dieser Anliegen kann von verschiedenen Bearbeitern in der Kette bearbeitet werden, was eine klare Trennung der Verantwortlichkeiten und einen modularen Code ermöglicht. Dieses Muster ist auch in Middleware-Architekturen von Vorteil, in denen verschiedene Middleware-Komponenten Anfragen verarbeiten können, was eine flexible Verarbeitung basierend auf bestimmten Kriterien ermöglicht.

Struktur des Chain-of-Responsibility-Musters

Das CoR-Muster besteht aus drei Schlüsselkomponenten: dem Handler, den Betonhandlern und dem Kunden. Der Handler definiert die Schnittstelle zur Bearbeitung von Anfragen und verwaltet einen Verweis auf den nächsten Handler in der Kette. Jeder Konkrete Handler implementiert die Logik für eine bestimmte Art der Anforderungsverarbeitung und entscheidet, ob die Anforderung bearbeitet oder an den nächsten Handler weitergeleitet wird. Der Client sendet Anfragen an die Handler-Kette, ohne zu wissen, welcher Handler die Anfrage letztendlich verarbeiten wird. Diese Entkopplung fördert die Wartbarkeit und Flexibilität im Backend-System.

Beispielimplementierung in Java

Schritt 1: Definieren Sie die Handler-Schnittstelle

Zuerst definieren wir eine RequestHandler-Schnittstelle, die Methoden zum Festlegen des nächsten Handlers und zum Verarbeiten von Anforderungen enthält:

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);
        }
    }
}

Schritt 2: Erstellen Sie Betonumschlaggeräte

Als nächstes erstellen wir konkrete Handlerklassen, die die RequestHandler-Klasse erweitern und jeweils für einen bestimmten Aspekt der Anforderungsverarbeitung verantwortlich sind:

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.");
        }
    }
}

Schritt 3: Einrichten der Kette

Jetzt richten wir die Kette der Bearbeiter basierend auf ihren Verantwortlichkeiten ein:

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);
    }
}

Schritt 4: Kundencode

So interagiert der Clientcode mit der Anforderungsverarbeitungskette:

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);
    }
}

Unterstützende Klasse

Hier ist eine einfache Request-Klasse, die zum Kapseln der Anfragedaten verwendet wird:

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;
    }
}

Ausgabeerklärung

Wenn Sie den Clientcode ausführen, werden Sie die folgende Ausgabe beobachten:

Authentication successful.
Authorization successful.
Data validation successful.
Processing business logic...
Authentication successful.
Authorization failed.
Request is invalid. Cannot process business logic.
  • Die erste Anfrage wird von allen Handlern erfolgreich verarbeitet, was zeigt, dass die gesamte Kette wie beabsichtigt funktioniert.
  • Die zweite Anfrage schlägt während des Autorisierungsschritts fehl, wodurch die weitere Verarbeitung gestoppt und verhindert wird, dass ungültige Anfragen die Geschäftslogik erreichen.

Vorteile des Chain-of-Responsibility-Musters

  1. Trennung von Belangen: Jeder Handler hat eine eigene Verantwortung, wodurch der Code leichter zu verstehen und zu warten ist. Durch diese Trennung können sich Teams auf bestimmte Aspekte der Anfragebearbeitung konzentrieren, ohne sich um den gesamten Arbeitsablauf kümmern zu müssen.

  2. Flexible Anfragebearbeitung: Handler können hinzugefügt oder entfernt werden, ohne die bestehende Logik zu ändern, was eine einfache Anpassung an neue Anforderungen oder Änderungen der Geschäftsregeln ermöglicht. Diese Modularität unterstützt agile Entwicklungspraktiken.

  3. Verbesserte Wartbarkeit: Die entkoppelte Natur der Handler bedeutet, dass Änderungen in einem Handler (z. B. die Aktualisierung der Validierungslogik) keine Auswirkungen auf andere haben, wodurch das Risiko der Einführung von Fehlern in das System minimiert wird.

  4. Einfacheres Testen: Einzelne Handler können isoliert getestet werden, was den Testprozess vereinfacht. Dies ermöglicht gezielte Komponententests und ein einfacheres Debuggen bestimmter Anforderungsverarbeitungsschritte.

Nachteile

  1. Leistungsaufwand: Eine lange Kette von Handlern kann zu Latenz führen, insbesondere wenn viele Prüfungen nacheinander durchgeführt werden müssen. Bei leistungskritischen Anwendungen könnte dies zu einem Problem werden.

  2. Komplexität in der Flusskontrolle: Während das Muster die Verantwortlichkeiten einzelner Handler vereinfacht, kann es den gesamten Ablauf der Anfragebearbeitung komplizieren. Um zu verstehen, wie Anfragen von mehreren Bearbeitern verarbeitet werden, ist für neue Teammitglieder möglicherweise zusätzliche Dokumentation und Aufwand erforderlich.

Abschluss

Das Chain of Responsibility-Muster ist ein effektives Entwurfsmuster in der Backend-Entwicklung, das die Anforderungsverarbeitung verbessert, indem es die Trennung von Anliegen, Flexibilität und Wartbarkeit fördert. Durch die Implementierung dieses Musters zur Anforderungsvalidierung und -verarbeitung können Entwickler robuste und skalierbare Systeme erstellen, die in der Lage sind, verschiedene Anforderungen effizient zu bearbeiten. Ob in einer RESTful-API, Middleware-Verarbeitung oder anderen Backend-Anwendungen, die Übernahme des CoR-Musters kann zu saubererem Code und verbessertem Architekturdesign führen, was letztendlich zu zuverlässigeren und wartbareren Softwarelösungen führt.

Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/syridit118/understanding-the-chain-of-responsibility-design-pattern-in-backend-development-p2f?1 Bei Verstößen wenden Sie sich bitte an Study_golang@163 .com, um es zu löschen
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3