当前位置: 首页 > 面试题库 >

与类别列表相比,责任链有什么优势?

石臻
2023-03-14
问题内容

最近,我正在与另一位程序员讨论重构充满“ if”语句的巨大(1000行)方法的最佳方法。

该代码是用Java编写的,但我想这个问题也可能在其他语言(例如C#)中发生。

为了解决这个问题,他建议使用责任链模式。他建议开设一个基本的“处理程序”类。然后,“ Handler1”,“ Handler2”等将扩展“
Handler”。
然后,处理程序将具有“ getSuccessor”方法,该方法将返回null(如果它是链的最后一个)或返回链的下一个Handler。
然后,“
handleRequest(Request)”函数将处理Request或将其传递到链的下一个,如果先前的解决方案均不起作用,它将仅返回null或引发异常。
要向链中添加新的Handler,编码人员将转到链的最后一个元素,并告诉它有一个新元素。为了做某事,他只需要在链的第一个元素上调用handleRequest。

为了解决此问题,我建议使用其他方法。
我也会有一个基本的“ Handler”类,分别带有“ Handler1”,“ Handler2”,就像前面提到的方法一样。
但是,将没有“
getSuccessor”方法。相反,我有一个带有处理程序列表的Collection类(一个Vector,一个ArrayList或在这种情况下最好的任何东西)。
handleRequest函数将仍然存在,但不会将调用传播到下一个处理程序。它只会处理请求或返回null。
要处理一个请求,可以使用

for(Handler handle : handlers){
    result = handle.handleRequest(request);
    if(result!=null) return result;
}
throw new CouldNotParseRequestException(); //just like in the other approach

或者,为防止代码重复,可以将“ parseRequest(request)”方法添加到集合类中。要添加一个新的处理程序,可以转到集合构造函数(或static
{}块,或等价的东西),然后简单地添加代码“ addHandler(new Handler3());”。

正是这种方法使我失去了责任链的哪些优势?哪种方法最好(假设 一个最好的方法)?为什么?每种设计方法可能导致哪些潜在的错误和问题?

对于那些需要上下文的人,原始代码如下所示:

if(x instanceof Type1)
{
//doSomething1
} else if(x instanceof Type2)
{
//doSomething2
}
//etc.

问题答案:

我比其他继任者更喜欢您的收藏理念。它使操作这组处理程序变得简单明了:collections接口是众所周知的,每个人都知道如何遍历List或不进行迭代。

如果您使用朋友建议的这种后继方式,请注意不要陷入非常深层次的递归中(除非您的平台支持尾部调用,否则我不知道JVM是否能够做到这一点)。

我不建议向集合中添加任何方法。您将获得更加复杂的设计,难以理解和修改。有两个单独的问题:存储一组处理程序,并将此处理程序解释为责任链。通过对集合进行迭代来处理请求的方法比集合内务管理方法具有更高的抽象级别,因此不应属于集合接口。



 类似资料:
  • 问题内容: 与常规Python列表相比,NumPy有什么优势? 我有大约100个金融市场系列,我将创建一个100x100x100 = 1百万个单元的多维数据集数组。我将每个x与y和z回归(3变量),以用标准误差填充数组。 我听说对于“大型矩阵”,出于性能和可伸缩性的原因,我应该使用NumPy而不是Python列表。事实是,我知道Python列表,它们似乎对我有用。 如果我转到NumPy,会有什么好

  • 问题内容: 用…实现事情 似乎 已经 很简单 了… 与 ngResource相比 ,使用Restangular 有哪些优点/缺点? 1.1.3 将返回承诺,并且可以使用[最新的PRcommit来实现。将来会提供支持来支持Restangular所做的其他动词吗?如果发生这种情况,Restangular似乎将消失并变得不耐烦。 问题答案: 我是Restangular的创建者。 我已经在自述文件中创建了

  • 问题内容: Java 5以Executor框架的形式引入了对线程池执行异步任务的支持,其核心是java.util.concurrent.ThreadPoolExecutor实现的线程池。Java 7以java.util.concurrent.ForkJoinPool的形式添加了备用线程池。 查看它们各自的API,ForkJoinPool在标准情况下提供了ThreadPoolExecutor功能的超

  • 所以,由于我是一个电工和程序员,我认为我对FSM设计模式非常了解。它是: 我们有一组, 每个都知道,当程序位于此节点时,要做什么, 每个的引用,并且知道在什么条件下,他应该继续到选定的节点。 在或节点后,到下一个选择的节点 我想,这对我来说很清楚。尽管最近,当我在实现一个状态机时,一个人告诉我,它实际上是一个稍微修改过的责任链(不确定他是否正确),并且,我所做的/所拥有的是: 一组(不表示线性或树

  • 问题内容: 过去,我的几个Ajax应用程序都使用GET请求,但是现在我开始使用POST请求。POST请求似乎更安全,并且绝对更友好/漂亮。因此,我想知道是否有任何原因使我应该使用GET请求。 问题答案: 我通常这样设置问题: 请求后有什么重要的变化吗? (尽管有日志记录等)。如果是,则应该是POST请求,如果不是,则应该是GET请求。 我很高兴您将POST请求称为“稍微”更安全,因为这几乎就是它们

  • Kotlin代码是这样的: 可以简单地更改为 我知道同伴对象可以用来作为真正的java静态函数使用,但是使用同伴对象还有其他的优点吗?