загрузка...

Цепочка обязанностей

Шаблон проектирования
поведенческий
Chain of responsibility
Тип:

поведенческий

Назначение:

для организации в системе уровней ответственности

Родственные шаблоны:

Компоновщик

Описан в Design Patterns

Да

Цепочка обязанностей — поведенческий шаблон проектирования, предназначенный для организации в системе уровней ответственности.

Содержание

  • 1 Применение
  • 2 Примеры
    • 2.1 Пример на Java
    • 2.2 Пример на C#
    • 2.3 Пример на C++
  • 3 Источники
  • 4 Ссылки

Применение

Шаблон рекомендован для использования в условиях:

  • в разрабатываемой системе имеется группа объектов, которые могут обрабатывать сообщения определенного типа;
  • все сообщения должны быть обработаны хотя бы одним объектом системы;
  • сообщения в системе обрабатываются по схеме «обработай сам либо перешли другому», то есть одни сообщения обрабатываются на том уровне, где они получены, а другие пересылаются объектам иного уровня.

Примеры

Пример на Java

Исходный текст на Java
/**
 * Абстрактный класс объектов, взаимодествующих посредством паттерна "Посредник"
 */
public abstract class Colleague {
 
    protected Mediator mediator;
 
    public Colleague(Mediator mediator) {
        this.mediator = mediator;
    }
 
    /**
     * Отправка сообщения посредством посредника
     * @param message сообщение
     */
    public void send(String message) {
        mediator.Send(message, this);
    }
 
    /**
     * Обработка полученного сообщения реализуется каждым конкретным
     * наследником
     * @param message получаемое сообщение
     */
    public abstract void notify(String message);
}
 
/**
 * Абстрактный класс "Посредник"
 */
public abstract class Mediator {
 
    /**
     * Отправка сообщения {@code message} указанному получателю {@code colleague}
     * @param message отправляемое сообщение
     * @param colleague получатель сообщения
     */
    public abstract void Send(String message, Colleague colleague);
}
 
/** Коллега 1 */
public class ConcreteColleague1 extends Colleague {
 
    public ConcreteColleague1(Mediator mediator) {
        super(mediator);
    }
 
    @Override
    public void notify(String message) {
        System.out.println("Colleague1 gets message: " + message);
    }
}
 
/** Коллега 2 */
public class ConcreteColleague2 extends Colleague {
 
    public ConcreteColleague2(Mediator mediator) {
        super(mediator);
    }
 
    @Override
    public void notify(String message) {
        System.out.println("Colleague2 gets message: " + message);
    }
}
 
/**
 * Посредник, реализующий конкретный алгоритм отправки сообщений между двумя
 * типами получателей {@code ConcreteColleague1} и {@code ConcreteColleague2}
 */
public class ConcreteMediator extends Mediator {
 
    private ConcreteColleague1 colleague1;
    private ConcreteColleague2 colleague2;
 
    public void setColleague1(ConcreteColleague1 colleague) {
        this.colleague1 = colleague;
    }
 
    public void setColleague2(ConcreteColleague2 colleague) {
        this.colleague2 = colleague;
    }
 
    @Override
    public void send(String message, Colleague colleague) {
        if (colleague == colleague1) {
            colleague2.notify(message);
        } else {
            colleague1.notify(message);
        }
    }
}
 
/** Тестовый класс */
public class Main {
 
    public static void main(String[] args) {
        ConcreteMediator m = new ConcreteMediator();
 
        ConcreteColleague1 c1 = new ConcreteColleague1(m);
        ConcreteColleague2 c2 = new ConcreteColleague2(m);
 
        m.setColleague1(c1);
        m.setColleague2(c2);
 
        c1.send("How are you");
        c2.send("Fine, thanks");
    }
}

Пример на C#

Исходный текст на языке C#
// Chain of Responsibility pattern -- Structural example
 
using System;
 
namespace DoFactory.GangOfFour.Chain.Structural
{
  /// <summary>
  /// MainApp startup class for Structural
  /// Chain of Responsibility Design Pattern.
  /// </summary>
  class MainApp
  {
    /// <summary>
    /// Entry point into console application.
    /// </summary>
    static void Main()
    {
      // Setup Chain of Responsibility
      Handler h1 = new ConcreteHandler1();
      Handler h2 = new ConcreteHandler2();
      Handler h3 = new ConcreteHandler3();
      h1.SetSuccessor(h2);
      h2.SetSuccessor(h3);
 
      // Generate and process request
      int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 };
 
      foreach (int request in requests)
      {
        h1.HandleRequest(request);
      }
 
      // Wait for user
      Console.ReadKey();
    }
  }
 
  /// <summary>
  /// The 'Handler' abstract class
  /// </summary>
  abstract class Handler
  {
    protected Handler successor;
 
    public void SetSuccessor(Handler successor)
    {
      this.successor = successor;
    }
 
    public abstract void HandleRequest(int request);
  }
 
  /// <summary>
  /// The 'ConcreteHandler1' class
  /// </summary>
  class ConcreteHandler1 : Handler
  {
    public override void HandleRequest(int request)
    {
      if (request >= 0 && request < 10)
      {
        Console.WriteLine("{0} handled request {1}",
          this.GetType().Name, request);
      }
      else if (successor != null)
      {
        successor.HandleRequest(request);
      }
    }
  }
 
  /// <summary>
  /// The 'ConcreteHandler2' class
  /// </summary>
  class ConcreteHandler2 : Handler
  {
    public override void HandleRequest(int request)
    {
      if (request >= 10 && request < 20)
      {
        Console.WriteLine("{0} handled request {1}",
          this.GetType().Name, request);
      }
      else if (successor != null)
      {
        successor.HandleRequest(request);
      }
    }
  }
 
  /// <summary>
  /// The 'ConcreteHandler3' class
  /// </summary>
  class ConcreteHandler3 : Handler
  {
    public override void HandleRequest(int request)
    {
      if (request >= 20 && request < 30)
      {
        Console.WriteLine("{0} handled request {1}",
          this.GetType().Name, request);
      }
      else if (successor != null)
      {
        successor.HandleRequest(request);
      }
    }
  }
}
 
Output
ConcreteHandler1 handled request 2
ConcreteHandler1 handled request 5
ConcreteHandler2 handled request 14
ConcreteHandler3 handled request 22
ConcreteHandler2 handled request 18
ConcreteHandler1 handled request 3
ConcreteHandler3 handled request 27
ConcreteHandler3 handled request 20

Пример на C++

Исходный текст на языке C++
#include <iostream>
 
class Colleague;
class Mediator;
class ConcreteMediator;
class ConcreteColleague1;
class ConcreteColleague2;
 
class Mediator
{
public:
        virtual void Send(std::string message, Colleague *colleague)=0;
};
 
class Colleague
{
protected:
        Mediator *mediator;
public:
        Colleague(Mediator *mediator)
        {
                this->mediator=mediator;
        }
};
 
class ConcreteColleague1:public Colleague
{
public:
        ConcreteColleague1(Mediator *mediator):Colleague(mediator)
        {
        }
 
        void Send(std::string message)
        {
                mediator->Send(message, this);
        }
 
        void Notify(std::string message)
        {
                std::cout << "Colleague1 gets message " << message.c_str() << std::endl;
        }
};
 
class ConcreteColleague2:public Colleague
{
public:
        ConcreteColleague2(Mediator *mediator):Colleague(mediator)
        {
        }
 
        void Send(std::string message)
        {
                mediator->Send(message, this);
        }
 
        void Notify(std::string message)
        {
                std::cout << "Colleague2 gets message " << message.c_str() << std::endl;
        }
};
 
class ConcreteMediator:public Mediator
{
protected:
        ConcreteColleague1      *m_Colleague1;
        ConcreteColleague2      *m_Colleague2;
public:
        void SetColleague1(ConcreteColleague1 *c)
        {
                m_Colleague1=c;
        }
 
        void SetColleague2(ConcreteColleague2 *c)
        {
                m_Colleague2=c;
        }
 
        virtual void Send(std::string message, Colleague *colleague)
        {
                if (colleague==static_cast<Colleague*>(m_Colleague1))
                {
                        m_Colleague2->Notify(message);
                }
                else if (colleague==static_cast<Colleague*>(m_Colleague2))
                {
                        m_Colleague1->Notify(message);
                }
        }
};
 
int main(int argc, char **argv)
{
        ConcreteMediator *m = new ConcreteMediator();
 
        ConcreteColleague1 *c1 = new ConcreteColleague1(m);
        ConcreteColleague2 *c2 = new ConcreteColleague2(m);
 
        m->SetColleague1(c1);
        m->SetColleague2(c2);
 
        c1->Send("How are you");
        c2->Send("Fine, thanks");
 
        std::cin.get();
        return 0;
}
 
Output
Colleague2 gеts message How are you
Colleague1 gеts message Fine, thanks

Источники

Ссылки

  • Паттерн Chain of Responsibility (цепочка обязанностей) — назначение, описание, особенности и реализация на С++.
  Шаблоны проектирования
Основные

Делегирования • Интерфейс • Неизменяемый объект • Функционального дизайна

Порождающие

Абстрактная фабрика • Объектный пул • Одиночка • Отложенная инициализация • Прототип • Строитель • Фабричный метод

Структурные

Адаптер • Выделение частного класса данных • Декоратор • Заместитель • Компоновщик • Мост • Приспособленец • Фасад

Поведенческие

Интерпретатор • Итератор • Команда • Наблюдатель • Посетитель • Посредник • Состояние • Стратегия • Хранитель • Цепочка обязанностей Шаблонный метод

Параллельного
программирования

Блокировка с двойной проверкой • Однопоточное выполнение • Планировщик


Источник: Русская википедия 2012

Искать все статьи, похожие на текущую (Цепочка обязанностей)
Вы можете разместить ссылку на этот материал у себя на сайте, блоге или форуме

HTML-cсылка на публикацию
BB-cсылка на публикацию (для форумов)
Прямая ссылка на публикацию


Это интересно! Зеркало   Плавание на летних Олимпийских играх 1904 — 220 ярдов вольным стилем   отторгавший   Камета   4040   
Универсальная энциклопедия 2012
Карта сайта
Страница создана за 0.082471 сек. Всего документов включено в базу знаний: 5150576