Цепочка обязанностей (Chain of responsibility) :: Cетевой уголок Majestio

Цепочка обязанностей (Chain of responsibility)


Цепочка обязанностей — это поведенческий паттерн проектирования, который позволяет передавать запросы последовательно по цепочке обработчиков. Каждый последующий обработчик решает, может ли он обработать запрос сам и стоит ли передавать запрос дальше по цепи.

Применимость

Подробнее на 👉 refactoring.guru

UML-диаграмма

Пример реализации

#include <iostream>

// Handler (в виде интерфейса)

class Handler {
 public:
  virtual void setNextHandler(Handler* nextHandler) = 0;
  virtual void handleRequest(const std::string& request) = 0;
};

// BaseHandler

class BaseHandler : public Handler {
 private:
  Handler* nextHandler;

 public:
  BaseHandler() : nextHandler(nullptr) {}

  void setNextHandler(Handler* nextHandler) override {
    this->nextHandler = nextHandler;
  }

  void handleRequest(const std::string& request) override {
    if (nextHandler) {
      nextHandler->handleRequest(request);
    } else {
      std::cout << "Запрос не может быть обработан" << std::endl;
    }
  }
};

// ConcreteHandler1

class ConcreteHandler1 : public BaseHandler {
 public:
  void handleRequest(const std::string& request) override {
    if (request == "Двигатель") {
      std::cout << "Обработчик 1: Работа с двигателем" << std::endl;
    } else {
      BaseHandler::handleRequest(request);
    }
  }
};

// ConcreteHandler2

class ConcreteHandler2 : public BaseHandler {
 public:
  void handleRequest(const std::string& request) override {
    if (request == "Кузов") {
      std::cout << "Обработчик 2: Работа с кузовом" << std::endl;
    } else {
      BaseHandler::handleRequest(request);
    }
  }
};

// Client

int main() {
  Handler* handler1 = new ConcreteHandler1();
  Handler* handler2 = new ConcreteHandler2();
  handler1->setNextHandler(handler2);

  handler1->handleRequest("Двигатель");
  handler1->handleRequest("Кузов");
  handler1->handleRequest("Подвеска");

  delete handler1;
  delete handler2;

  return 0;
}
Будет напечатано:
Обработчик 1: Работа с двигателем
Обработчик 2: Работа с кузовом
Запрос не может быть обработан
abstract class Handler {
  void setNextHandler(Handler? nextHandler);
  void handleRequest(String request);
}

class BaseHandler implements Handler {
  Handler? nextHandler;

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

  void handleRequest(String request) {
    if (nextHandler != null) {
      nextHandler!.handleRequest(request);
    } else {
      print('Запрос не может быть обработан');
    }
  }
}

class ConcreteHandler1 extends BaseHandler {
  void handleRequest(String request) {
    if (request == 'Двигатель') {
      print('Обработчик 1: Работа с двигателем');
    } else {
      super.handleRequest(request);
    }
  }
}

class ConcreteHandler2 extends BaseHandler {
  void handleRequest(String request) {
    if (request == 'Кузов') {
      print('Обработчик 2: Работа с кузовом');
    } else {
      super.handleRequest(request);
    }
  }
}

void main() {
  var handler1 = ConcreteHandler1();
  var handler2 = ConcreteHandler2();
  handler1.setNextHandler(handler2);

  handler1.handleRequest('Двигатель');
  handler1.handleRequest('Кузов');
  handler1.handleRequest('Подвеска');
}
Будет напечатано:
Обработчик 1: Работа с двигателем
Обработчик 2: Работа с кузовом
Запрос не может быть обработан
Рейтинг: 0/5 - 0 голосов