**Պարտականությունների շղթա** (անգլ.՝ Chain of responsibility), վարքագծային նախագծման ձևանմուշ, որը նախատեսված է համակարգում պատասխանատվությունների բաշխումը իրականացնելու համար։

Ընդհանուր հասկացողություններ
----------------------------

* Client - հայցող
* Instance - նմուշ
* Implementation - իրականացում
* Product - արգասիք

Կիրառություն
------------

Ձևանմուշը խորհուրդ է տրվում օգտագործել, երբ.

* մշակվող համակարգում կա օբյեկտների խումբ, որոնք մշակում են հատուկ տիպի հաղորդագրություններ
* բոլոր հաղորդագրությունները պետք է մշակվեն համակարգի գոնե մեկ օբյեկտի կողմից
* համակարգում հաղորդագրությունները մշակվում են հետևյալ տրամաբանությամբ. «մշակիր ինքդ կամ ուղարկիր մյուսին»։ Այսինքն հաղորդագրություններից ոմանք մշակվում են այն մակարդակում, որտեղ որ ստացվել են, իսկ մյուսներն ուղարկվում են մյուս մակարդակի օբյեկտներին։

Օրինակներ
---------

### 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

```

### 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

```

### Java

{{Hider\_hiding
| title = Исходный текст на Java
| content-style = text-align։ left;
| content =

```
package chainofresp;
 
abstract class Logger {
 public static int ERR = 3;
 public static int NOTICE = 5;
 public static int DEBUG = 7;
 protected int mask;
 
 // The next element in the chain of responsibility
 protected Logger next;
 
 public Logger setNext(Logger log) {
 next = log;
 return log;
 }
 
 public void message(String msg, int priority) {
 if (priority <= mask) {
 writeMessage(msg);
 }
 if (next != null) {
 next.message(msg, priority);
 }
 }
 
 abstract protected void writeMessage(String msg);
}
 
class StdoutLogger extends Logger {
 public StdoutLogger(int mask) { 
 this.mask = mask;
 }
 
 protected void writeMessage(String msg) {
 System.out.println("Writing to stdout: "+ msg);
 }
}
 
 
class EmailLogger extends Logger {
 public EmailLogger(int mask) {
 this.mask = mask;
 }
 
 protected void writeMessage(String msg) {
 System.out.println("Sending via email: "+ msg);
 }
}
 
class StderrLogger extends Logger {
 public StderrLogger(int mask) {
 this.mask = mask;
 }
 
 protected void writeMessage(String msg) {
 System.out.println("Sending to stderr: "+ msg);
 }
}
 
public class ChainOfResponsibilityExample {
 public static void main(String[] args) {
 // Build the chain of responsibility
 Logger logger, logger1,logger2;
 logger = new StdoutLogger(Logger.DEBUG);
 logger1 = logger.setNext(new EmailLogger(Logger.NOTICE));
 logger2 = logger1.setNext(new StderrLogger(Logger.ERR));
 
 // Handled by StdoutLogger
 logger.message("Entering function y.", Logger.DEBUG);
 
 // Handled by StdoutLogger and EmailLogger
 logger.message("Step1 completed.", Logger.NOTICE);
 
 // Handled by all three loggers
 logger.message("An error has occurred.", Logger.ERR);
 }
}
/\*
The output is:
 Writing to stdout: Entering function y.
 Writing to stdout: Step1 completed.
 Sending via e-mail: Step1 completed.
 Writing to stdout: An error has occurred.
 Sending via e-mail: An error has occurred.
 Writing to stderr: An error has occurred.
\*/

```

Ծանոթագրություններ
------------------



|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * դ
* ք
* խ
Նախագծման ձևանմուշներ |
| --- |
|  |
| ԳօՖիձևանմուշներ | 

|  |  |
| --- | --- |
| Ստեղծող | Աբստրակտ ֆաբրիկա • Կառուցող • Ֆաբրիկային մեթոդ • Նախատիպ • Եզակի օգտագործման |
| Կառուցվածքային | Ադապտեր • Կամուրջ • Կազմող • Դեկորատոր • Ճակատ • Հարմարեցնող • Պրոքսի |
| Վարքագծային | Պարտականությունների շղթա • Հրաման • Թարգմանիչ • Իտերատոր • Միջնորդ • Պահպանող • Դիտորդ • Վիճակ • Մարտավարություն • Կաղապարային մեթոդ • Այցելող |

 |
|  |
| Ստեղծող ձևանմուշներ | Ծույլ բեռնում • Բազմակի օգտագործման • Օբյեկտների ավազան • Ռեսուրսի ստանալը ինիցիալիզացիա է |
|  |
| Կառուցվածքային ձևանմուշներ | Ճակատը հսկող • Մոդուլ |
|  |
| Համաձայնեցման ձևանմուշներ | Ակտիվ օբյեկտ • Հենվող • Մեկուսացում կրկնակի ստուգումով • Ասինքրոն կանչի մեթոդ • Պահպանվող կախոց • Ռեգիստրացնող • Կողպեքավորող • Մոնիտոր • Նախագործող • Ապագործող • Ընթերցողներ-գրողի կողպեք • Պլանավորման • Հոսքերի ավազանի • Հոսքերի լոկալ հիշողություն |
|  |
| Ճարտարապետական ձևանմուշներ | Ճակատը հսկող ձևանմուշ • Զավթող ձևանմուշ • ձևանմուշի ներկայացման վերահսկում • Բազմաշերտ • Հատկորոշում • Հրատարակող-ստորագրող • Մերկ օբյեկտներ • Ծառայության լոկատոր • Ակտիվ գրառման • Բազմության իդենտիֆիկացման • Data access object • Data transfer object |
|  |
| Այլ ձևանմուշներ | Կախվածության ներդնում • Mock օբյեկտ • Զրոյական օբյեկտ • Ծառայող • Թունելային տարատեսակի |

 |