Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 责任链模式_Design Patterns_Chain Of Responsibility - Fatal编程技术网

Design patterns 责任链模式

Design patterns 责任链模式,design-patterns,chain-of-responsibility,Design Patterns,Chain Of Responsibility,有人能简单解释一下责任链模式吗?我发现这篇wiki文章有点让人困惑。一个很好的例子是——在HTTP请求到达目标之前执行的代码片段 该链包含多个实例,每个实例执行不同的操作 链中的每个实例都可以选择传播到下一个实例,或者停止流 因此,使用servlet过滤器,您可以 检查用户是否经过身份验证的筛选器。如果他是,过滤器将传播到下一个过滤器 下一个筛选器检查用户是否具有对当前资源的权限。如果是,它将传播到下一个 next记录当前请求URL和用户名,并始终传播到next 链中没有其他内容,因此最终

有人能简单解释一下责任链模式吗?我发现这篇wiki文章有点让人困惑。

一个很好的例子是——在HTTP请求到达目标之前执行的代码片段

  • 该链包含多个实例,每个实例执行不同的操作
  • 链中的每个实例都可以选择传播到下一个实例,或者停止流
因此,使用servlet过滤器,您可以

  • 检查用户是否经过身份验证的筛选器。如果他是,过滤器将传播到下一个过滤器

  • 下一个筛选器检查用户是否具有对当前资源的权限。如果是,它将传播到下一个

  • next记录当前请求URL和用户名,并始终传播到next

  • 链中没有其他内容,因此最终将调用目标对象


使用此模式,您可以创建一个检查请求的对象链每个人依次检查请求并处理它或将其传递给链中的下一个对象

利益
  • 分离请求的发送方和接收方
  • 简化对象,因为它不必知道链结构并保留对其成员的引用
  • 允许通过更改链的顺序或成员动态添加或删除责任
缺点
  • 请求的执行没有保证,如果没有对象处理它,它可能会从链上掉下来
  • 运行时特性可能很难观察和调试
潜在用例
  • 鼠标点击和键盘事件
  • 电子邮件。例如,电子邮件被接收并传递给第一个处理程序,即垃圾邮件处理程序。然后,它被处理或传递给第二个处理程序,等等
发件人:



下面是关于此模式的一个有趣的示例代码。

我将借助一个类比来尝试:

想象一下,命令被当作冰球处理,责任链处理程序被当作带单孔的网。现在想象一下,这种不同半径的网彼此堆叠在一起(顶部有最小半径孔的网)

现在你把冰球从上面扔下来。如果冰球的半径大于第一个洞,它将被卡在里面而不会下降。表示该命令已由第一个处理程序处理


但是,如果冰球比洞小,它会穿过洞进入下一个洞,以此类推,直到它被抓住或掉进所有的网中。puck所经历的所有网络(责任处理程序类)都处理了puck(处理该命令)。

post受到保护,但我想给出一个答案,因为我认为它可能会得到改进

责任链和过滤器。它们是一样的吗?

过滤模式与责任链模式相近
但是,不把它们混在一起就足够了。
用同一个词来表达两个截然不同的概念将是一种遗憾

在过滤器/拦截器模式中,我们没有责任的概念,因为链的多个节点可能作用于同一个流,并且在模式的意图中,它是为多个处理创建的。链的节点不处理请求,它们共同参与请求的处理。
因此,过滤器或拦截器与其说是责任链,不如说是处理链。
例如,面向方面编程(AOP)充当过滤器和拦截器。我们希望从一堆处理器中重复一些处理。
这不是责任问题,而是我们是否根据某些条件应用多层处理的问题。它对实现及其背后的逻辑具有重要影响。
存储在链中的过滤器/拦截器之间可能(通常)没有逻辑或功能关系,而责任链的节点之间始终有逻辑或功能关系,因为它们必须处理相同的问题。 例如,在链式筛选器中,第一个筛选器可能处理日志问题,第二个筛选器处理安全问题,最后一个筛选器处理编码问题
在责任链中,相同的问题由链中的所有节点处理

GOF参考 责任链意图:

通过给多个对象一个处理请求的机会,避免将请求的发送方与其接收方耦合。链接接收对象并沿链传递请求,直到对象处理它。 在责任链模式中,当链的一个节点处理该事件时,链停止


现在,我将用一个简单而具体的例子简要描述它是什么以及何时使用它

什么是责任链?

责任链设计模式是一种行为模式。 正如所有GOF设计模式一样,它的名字非常适合它,因为该模式定义了一个要处理的请求,一个对象链,一个接一个地具有停止链处理和响应请求的能力。 此模式提供了将链的组件解耦的优势。因此,我们可以独立更新组件并动态创建链

在使用责任链时?

在责任链中,只有单个对象可以负责响应请求。如果我们希望不止一名候选人能够按照要求行事,我们就远离责任链模式。我们处于一个加工链中。过滤器模式解决了这种需求

责任链模式应用于多种环境:技术和业务

在用户界面中处理内部事件和用户事件是一种常见用法。 在这种情况下,第
using System;

// The 'Handler' abstract class
abstract class Handler
{
    //chain link
    private Handler _successor;
    //
    static private Handler _first;

    public Handler Successor
    {
        set 
        {
            _successor = value;
        }
        get 
        {
            return _successor;
        }
    }
    public Handler First
    {
        set 
        {
            _first = value;
        }
        get 
        {
           return  _first;
        }
    }
    //
    public void HandleRequest(string request)
    {
        if (First == this)
        {
            Console.WriteLine("\n\tWe translate word => \"{0}\"\n", request);
            First.Translator(request);
        }
        //
        if (Successor != null)
        {
            //Translation by the successor's dictionary 
            Successor.Translator(request);

            //Transfer of word (request) to another chain (dictionary) 
            Successor.HandleRequest(request);
        }
    }
    //
    abstract public void Translator(string word);
}

//The concrete class
class GermanDictionary : Handler
{
    override public void Translator(string word)
    {
        switch (word)
        {
            case "Job":
                word = "Arbeit";
                break;
            case "Rest":
                word = "Rest";
                break;
        }
        Console.WriteLine("\t\tinto German => \"{0}\"", word);
    }
}

class FrenchDictionary : Handler
{
    override public void Translator(string word)
    {
        switch (word)
        {
            case "Job":
                word = "Travail";
                break;
            case "Rest":
                word = "Reste";
                break;
        }
        Console.WriteLine("\t\tinto French => \"{0}\"", word);
    }
}

class PolishDictionary : Handler
{
    override public void Translator(string word) 
    {
        switch (word)
        {
            case "Job":
                word = "Praca";
                break;
            case "Rest":
                word = "Odpoczynek";
                break;
        }
        Console.WriteLine("\t\tinto Polish => \"{0}\"", word);
    }
}
////
class Client
{
    static void Main()
    {
        Handler h1 = new FrenchDictionary();
        Handler h2 = new GermanDictionary();
        Handler h3 = new PolishDictionary();

        //Determining the consequences in the chain
        h1.First=h1;
        h1.Successor=h2;
        h2.Successor=h3;
        h3.Successor=null;

        //The word that is translated
        string request = "Job";

        //Starting the recursive method.
        h1.HandleRequest(request) ;

        //Another word is translated.
        request = "Rest";
        h1.HandleRequest(request);

        Console.ReadKey();
    }
}

/*output:

 We translate word => "Job"

    into French => "Travail"
    into German => "Arbeit"
    into Polish => "Praca"

 We translate word => "Rest"

    into French => "Reste"
    into German => "Rest"
    into Polish => "Odpoczynek"
 */