lui*_*bal 17 java list chain-of-responsibility
最近,我正在与另一个程序员讨论重构一个充满"if"语句的巨大(1000行)方法的最佳方法.
代码是用Java编写的,但我想这个问题也可能发生在C#等其他语言中.
为了解决这个问题,他建议使用责任链模式.他建议有一个基础"处理程序"类.然后,"Handler1","Handler2"等将扩展"Handler".
然后,处理程序将具有"getSuccessor"方法,该方法将返回null(如果它是链的最后一个)或链的下一个Handler.
然后,"的handleRequest(请求)"功能,要么处理请求,或者将它传递给下一个链条,如果没有以前的解决方案的工作,它将返回空值只是或抛出异常.
要向链中添加新的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
Run Code Online (Sandbox Code Playgroud)
或者,为了防止代码重复,可以将"parseRequest(request)"方法添加到集合类中.要添加一个新的处理程序,可以转到集合构造函数(或static {}块,或者等价物)并简单地添加代码"addHandler(new Handler3());".
对于这种方法,我错过了什么样的责任链优势?哪种方法最好(假设是一个最好的方法)?为什么?每种设计方法可能导致哪些潜在的错误和问题?
对于那些需要上下文的人来说,这是原始代码的样子:
if(x instanceof Type1)
{
//doSomething1
} else if(x instanceof Type2)
{
//doSomething2
}
//etc.
Run Code Online (Sandbox Code Playgroud)
哪种方法最好取决于您的处理程序想要做什么.
如果处理程序可以完全处理请求请求,那么您的方法就可以了.处理程序没有对其他处理程序的引用,这使得处理程序接口变得简单.与Chain of Responsibility的标准实现不同,您可以从链的中间添加或删除处理程序.实际上,您可以根据请求的类型选择构建不同的链.
您的方法的一个问题是处理程序无法对请求进行预处理或后处理.如果需要此功能,则责任链更好.在CoR中,处理程序是负责委托链上的下一个处理程序的处理程序,因此处理程序可以进行预处理和/或后处理,包括修改或替换链上下一个处理程序的响应.通过这种方式,CoR与Decorator非常相似; 这只是意图的不同.
因为在CoR中,处理程序保留对链中下一个项的引用,所以不能在链的中间添加或删除项.允许您从链中间添加或删除项目的CoR变体是过滤器链(例如,参见javax.servlet.FilterChain).
您展示的代码示例是一堆"if"语句,它们根据对象的类型执行不同的行为.如果这是您正在清理的代码的典型情况,您可以简单地从请求类型到所需的处理程序.
删除"if"语句的另一种方法是继承.如果您需要执行某些操作,并且Web服务器有一个变体,而SOAP服务器有其他变体,则可以使用WebServerRequestHandler和SoapServerRequestHandler,每个都扩展RequestHandler.继承的优点是可以更清楚地放置两种类型的请求共有的逻辑.缺点是,由于Java没有多重继承,因此只能建模一维问题.
我喜欢你的想法,收藏比那些继承者更好.它使操作这组处理程序变得简单明了:集合接口是众所周知的,并且每个人都理解如何遍历List或不是.
如果你使用朋友建议的这种后继方式,请注意不要陷入非常深的递归(除非你的平台支持尾调用,我不知道JVM是否能够做到这一点).
我不建议在集合中添加任何方法.你会得到更复杂的设计,更难以理解和更难修改.有两个独立的问题:存储一组处理程序并将此处理程序的解释视为一个责任链.通过迭代集合来处理请求的方法比集合内务处理方法具有更高的抽象级别,因此不应属于集合接口.
| 归档时间: |
|
| 查看次数: |
4802 次 |
| 最近记录: |