什么是连锁的责任与类名单的优势是什么?(What are the advantages of cha

2019-06-24 09:03发布

最近,我与另一个程序员讨论重构一个巨大的(1000线)方法十足的“if”语句的最佳途径。

该代码是用Java编写的,但我想这个问题可以在其他语言如C#中发生为好。

为了解决这个问题,他建议使用链的责任模式。 他提出了具有一基地“处理程序”类。 那么, “Handler1”, “Handler2” 等将扩大 “处理程序”。
然后,处理程序将有一个“getSuccessor”方法,它要么返回null(如果它是最后一个链的)或链的下一个处理程序。
然后,“的handleRequest(请求)”功能,要么处理请求,或者将它传递给下一个链条,如果没有以前的解决方案的工作,它将返回空值只是或抛出异常。
若要将新处理器加入连锁,编码器会去链条的最后一个元素,并告诉它有一个新的元素。 做一些事情,他只需要调用的handleRequest链的第一个元素。

为了解决这个问题,我建议用不同的方法。
我有一个基地“处理程序”类为好,以“Handler1”,“Handler2”,就像前面提到的方法。
然而,就没有“getSuccessor”的方法。 相反,我有一个集合类的处理程序列表(矢量,一个ArrayList,或什么是最好在这种情况下)。
这个handleRequest功能仍然存在,但它不会传播调用next处理程序。 它只是处理请求或返回null。
为了处理一个请求,一个会用

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

或者,为了防止代码重复,一“的parseRequest(请求)”方法​​可以加入到集合类。 要添加新的处理程序,一个会去收集构造函数(或静态{}块,或某事equivaleng),只需添加代码“addHandler操作(新Handler3());”。

究竟是什么优势链方面的责任,我会用这种方法缺少什么? 哪种方法最好(假设一个最好的方法)? 为什么? 有什么潜在的bug,并可以各自设计方法造成的问题?

对于那些谁需要语境,这里看上去像什么的原代码:

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

Answer 1:

我喜欢收集比那些接班人更好的自己的想法。 它可以很容易和清晰的操作这套处理程序:集合接口是众所周知的,每个人都知道如何遍历List或什么不是。

如果您使用的一个朋友建议这个继任者的方式,小心不要陷入了非常深刻的递归(除非你的平台支持尾调用,我不知道的JVM能够说)。

我不会推荐添加任何方法来收集。 你得到更为复杂的设计,是很难理解和难以修改。 有两个单独的担忧:存储一组处理程序和责任链这个处理程序的解释。 通过遍历集合处理请求的方法是比抽象集合看家方法的较高水平,因此不应该属于采集接口。



Answer 2:

哪种方法最好取决于您的处理程序要做什么。

如果处理完全可以自己处理请求的要求,你的做法是好的。 处理程序没有参考其他处理,这使得处理程序界面简洁。 不同于标准落实责任链,可以从链的中间添加或移除处理程序。 事实上,你可以选择构建根据请求的类型不同的链。

你的方法的一个问题是,处理程序不能做前处理或后处理的请求。 如果需要此功能,那么责任链是较好的。 在COR,该处理程序是一个负责委派到链上的下一个处理,所以该处理程序可以做预处理和/或后处理,包括修改或替换从在链中的下一个处理程序的响应。 通过这种方式,COR是非常相似的装饰; 它只是是不同的意图。

由于肺心病,处理程序一直到链上的下一个项目的参考,你不能添加或从链中间删除项目。 它允许你从链的中间添加或删除项目COR的变化是一个过滤器链(参见,例如, javax.servlet.FilterChain )。

您显示的代码示例是一堆的基于对象的类型做了不同的行为“if”语句。 如果这是典型的为你清理的代码,你可以简单地从有请求类型所需要的处理程序映射。

去除“if”语句的另一种方法就是继承。 如果你有,你需要做的,并有一个Web服务器的一个变化,并为SOAP服务器的其他变化的一些行为,你可以有一个WebServerRequestHandler和SoapServerRequestHandler,各自延伸RequestHandler。 有继承其优点是有把逻辑是常见的两种类型的请求更清晰的地方。 其缺点是,由于Java没有多重继承,你只能模拟单维问题。



Answer 3:

不能告诉我们,如果责任链就是你的答案,或者即使GoF的应用。 游客可能是正确的事情。 没有足够的信息来加以确认。

这可能是你的问题可以用老式的多态性进行处理。 或者,也许是使用的键和地图挑选出合适的处理对象。

保持“做最简单的事情可能”的初衷。 直到你证明你自己,你需要它,不要飞跃到复杂。

最近,我读到有关反IF运动促进了这个想法。 听起来很中肯这里。



文章来源: What are the advantages of chain-of-responsibility vs. lists of classes?