загрузка...

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

Шаблон проектирования
поведенческий
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
{
public:
        virtual void Send(std::string message, Colleague *colleague)=0;
        virtual ~Mediator(){}
};
 
class Colleague
{
protected:
        Mediator *mediator;
public:
        Colleague(Mediator *mediator)
        {
                this->mediator=mediator;
        }
        virtual ~Colleague(){}
};
 
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сылка на публикацию (для форумов)
Прямая ссылка на публикацию


Это интересно! Узон   Фудзиока, Хироси   вытаскивание   NGC 716   Бритиков Анатолий Федорович   
Универсальная энциклопедия 2012
Карта сайта
Страница создана за 0.037847 сек. Всего документов включено в базу знаний: 5150576