Պարտականությունների շղթա (նախագծման ձևանմուշ)

Վիքիպեդիայից՝ ազատ հանրագիտարանից
Jump to navigation Jump to search
Պարտականությունների շղթա
Անգլերեն անվանում` Chain of responsibility
Տեսակ` Վարքագծային
Նշանակություն` համակարգում պատասխանատվությունների բաշխումը իրականացնելու համար
Նկարագրությունը ԳօՖի
"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.
*/

Ծանոթագրություններ[խմբագրել | խմբագրել կոդը]