问题标签 [chain-of-responsibility]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
1745 浏览

design-patterns - 责任链与拦截器

每个请求都通过定义在一个组中的拦截器发送,该组类似于创建为传递链的类。拦截器与责任链有何不同?

0 投票
2 回答
380 浏览

design-patterns - 责任链中的 HashMap 是对模式的滥用吗?

我已经看到了一个 CoR 模式的示例实现,它使用 HashMap 作为传递到链中的对象,可能会通过处理程序将新内容添加到其中;下面的代码大纲:

使用它很诱人,因为处理程序可以使用新信息来增强这些context信息,这些信息可以被后续处理程序使用,而无需重复代码。另一方面,处理程序变得相互依赖——它们仍然是松散耦合的,但它们的顺序仍然变得越来越重要。

这段代码有味道吗?如果我们发现如果不使用新信息补充上下文对象就无法使用 CoR 模式,那么在这种情况下使用什么模式才是正确的呢?

0 投票
3 回答
362 浏览

java - Java 模式:用于数据挖掘任务的工程数据流

我是一名数据挖掘者,因此,我花费大量时间以各种方式转换原始数据,以支持预测模型的消费。例如,以某种格式读取文件、标记化、语法化并投影为某种数字表示。多年来,我开发了一套丰富的方法来完成我能想到的大多数数据处理任务,但除了最基本的方式之外,我没有一个很好的方法来配置这些组件——通常我所做的是很多源代码中依赖于特定任务的特定方法的调用次数。我现在正在尝试将我的库重构为更好的东西,但我不太确定这是什么。

我目前的想法是,有一个函数对象列表,每个函数对象定义一些方法(比如,operate(...)),它们按顺序调用,每个对象要么通过引用处理某些数据流的内容,要么消耗前一个函数对象。这与我想要的很接近,但是由于输入和输出的数据类型会有所不同,因此使用泛型变得非常困难。要使用我上面的例子,我想通过这个处理数据的“管道”传递一些东西,比如:

这是一个简单的例子,但想象一下我有 100 个这样的组件,我想将它们添加到一些数据流中。这满足了我易于配置的要求——我可以轻松地构建一个管道工厂来读取一些 yaml 文件并将其构建出来。然而,组件的设计模式一直困扰着我一段时间?合适的接口是什么样的?似乎在这里做事的唯一简单方法是传递对象,本质上取消对象(或者传递一些将对象作为成员变量的上下文对象),然后在输入时检查兼容性,抛出运行时异常. 这两种选择似乎同样糟糕。然而,我觉得我在这里接近一个非常好的和灵活的系统。你们能帮我把它推过栅栏吗?

0 投票
1 回答
475 浏览

code-analysis - FxCop(/VS2010 代码分析),可以将方法结果标记为 IDisposable 的“现在调用者责任”吗?

如果我编写以下代码:

然后代码分析会将其标记为:

警告 1 CA2000:Microsoft.Reliability:在方法“ServiceUser.Execute()”中,在对对象“流”的所有引用超出范围之前调用 System.IDisposable.Dispose。C:\Dev\VS.NET\DisposeTest\DisposeTest\ServiceUser.cs 14 DisposeTest

但是,如果我创建工厂模式,我仍然可能需要处理对象,但现在 FxCop/代码分析不会抱怨。相反,它抱怨的是工厂方法,而不是调用它的代码。 (我想我有一个确实抱怨工厂方法的例子,但我在这里发布的那个没有,所以我把它删掉了)

有没有办法(例如使用属性)将 IDisposable 对象的责任从工厂方法转移到调用者身上?

拿这个代码:

在这种情况下,没有警告。我希望 FxCOP/CA 仍然抱怨我原来的方法。处理那个对象仍然是我的责任。

有什么办法可以告诉 FxCOP/CA?例如,我最近冒险研究了 ReSharper 提供的注释属性,以便告诉它的分析引擎信息,否则它无法理解。

所以我设想这样的事情:

或者这种设计方式有问题?

0 投票
2 回答
4010 浏览

java - Java 泛型:将泛型函数对象链接在一起

我一直在努力解决以下问题。我有一系列函数对象,每个函数对象都有自己的输入和输出类型,这些类型是通过 java 中的泛型类型参数定义的。我想将它们排列成一个链,以便原始数据输入到第一个函数,转换为输出类型,即下一个对象的输入类型,依此类推。当然,这对于硬编码来说是微不足道的,但我希望代码可以插入到新的函数对象中。如果我只是省略类型参数(只有最终输出类型),这就是事情的样子:

这里在函数对象之间传递数据的迭代器,上下文应该是上下文。有没有办法保持以下类型的管道可插拔并仍然保持类型安全?

编辑:为清楚起见,我有一系列功能对象,管道。每个都将特定类型作为输入并输出另一种类型。(实际上是这些类型的迭代器)这些将被链接在一起,例如 ,Pipe<A,B> -> Pipe<B,C> -> Pipe<C,D> -> ...以便一个管道的输出是下一个管道的输入类型。这里还有一个输出 A 类型迭代器的源和一个接受类型的接收器(过去管道的输出)。这会让事情变得更清楚吗?问题是,由于对输入和输出类型的兼容性存在严重依赖关系,有没有办法确保这一点?

我开始认为将函数对象插入管道可能是确保类型安全的最佳时机,但我不确定如何做到这一点。

编辑2:我有一个函数对象的加法器方法,目前如下所示:

我想检查第一个类型参数是否与当前管道的“结束”相同,如果不是则抛出异常?我不认为这里有一个很好的方法来获得编译时的安全性。然后可以将当前管道的“结束”设置为输入管道的第二种类型参数。我想不出如何使用泛型来做到这一点,并且传递类信息似乎非常可怕。

0 投票
1 回答
35 浏览

com - COM 可以与责任链模式一起使用吗

这个想法是COM接口有一个初级实现,它需要处理不同的MIME类型(MIME只是一个例子)。主要实现处理预期在客户站点上的几种常见 MIME 类型。

要处理新的 MIME 类型,必须实现相同的 COM 接口,但仅限于新的 MIME 类型(我们称之为增强型 COM 对象)。客户端首先调用增强型 COM 对象,该对象处理其 MIME 类型,如果 MIME 类型未被识别,则调用主 COM 对象。我们可以假设可能不止一种增强的 COM 实现。因此,有一个责任链。

COM 责任链可能吗?实用吗?

谢谢

0 投票
2 回答
3484 浏览

java - 如何以可测试的方式实现责任链?

我想实现一个责任链模式,处理“断开的链接”问题,如下所示:

似乎是一种足够普遍的方法。但是如何用受保护的抽象方法测试呢?处理这个问题的方法似乎是:

  1. Handler实现实现抽象方法的仅测试子类。这似乎不利于测试维护。
  2. 将抽象方法的可见性更改为公共,但我不需要更改 SUT 以适应测试。
  3. 将抽象类视为足够简单,不需要单元测试。嗯。
  4. handleRequest在一个或多个具体子类上为方法实施单元测试。但这似乎不是组织测试的明智方式。
  5. 有没有办法使用模拟对象?我试过 Mockito,但似乎无法绕过受保护的可见性。

我已经阅读[ 1 ],这种测试问题意味着设计是错误的,并建议使用组合而不是继承。我现在正在尝试这个,但是这个模式的推荐实现有这个问题似乎很奇怪,但我找不到任何关于单元测试的建议。

更新:我已经用依赖反转替换了抽象类,如图所示,现在可以使用 Mockito 轻松测试。它看起来仍然像责任链......我错过了什么吗?

0 投票
6 回答
3677 浏览

design-patterns - 责任链模式

有人可以提供责任链模式的简单解释吗?我发现维基文章有点混乱。

0 投票
1 回答
383 浏览

oracle - Oracle 程序中的 if-else 太多,性能好还是坏?

在一个过程中,我需要使用许多 if-else 条件来确定列的值。脚本以

FOR rec IN (SELECT....) 循环开始

并决定rec子记录在每次迭代中可以获得的许多不同值。在某些情况下,可能只有 2 或 3 个变量赋值,而某些情况包括运行单独的过程或执行 INSERT 操作。

如果循环的 SELECT 语句的结果有很多记录,这种方法是从性能方面进行决策的最佳方法,还是可能有更好的选择?如果我在编写此程序时采用责任链模式怎么办?这种方法会提高性能还是只会让事情变得更糟?

问候。

0 投票
2 回答
1005 浏览

c# - 执行责任链变化

我有一个任务管道,基本上是责任链模式的变体。

我的管道中的一个任务如下所示

..我的处理器看起来像

我的具体实现如下所示:

..我的任务如下所示:

T 可以是不同的实例,但受通用合同的约束。其中一项任务是将传入对象映射到完全不同的对象并从那里转发该实例。

现在如您所见,我正在执行管道中的所有任务,我想将其修改为以下内容:

  • 下一个任务的方法的输入Execute应该来自先前执行的任务。
  • 如果CanExecute任务失败,则管道应停止处理任务。

你能帮我弄到这个吗?此外,您是否希望为此目的代码结构不同?