Պարտականությունների շղթա (նախագծման ձևանմուշ)
Պարտականությունների շղթա | |
---|---|
Տեսակ | Վարքագծային |
Նշանակություն | համակարգում պատասխանատվությունների բաշխումը իրականացնելու համար |
Նկարագրությունը ԳօՖի "Design Patterns" գրքում | Այո |
Պարտականությունների շղթա (անգլ.՝ 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.
*/
|