责任链与类别列表相比有什么优势? [英] What are the advantages of chain-of-responsibility vs. lists of classes?

查看:86
本文介绍了责任链与类别列表相比有什么优势?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,我正在与另一位程序员讨论重构包含"if"语句的巨大(1000行)方法的最佳方法.

Recently, I was discussing with another programmer the best way to refactor a huge(1000 lines) method full of "if" statements.

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

The code is written in Java, but I guess this issue could happen in other languages such as C# as well.

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

To solve this problem, he suggested using a chain-of-responsibility pattern. He proposed having a base "Handler" class. Then, "Handler1", "Handler2", etc. would extend "Handler".
Then, handlers would have a "getSuccessor" method, which would either return null(if it was the last of the chain) or the next Handler of the chain.
Then, a "handleRequest(Request)" function would either deal with Request, or pass it to the next of the chain and, if none of the previous solutions worked, it would return just null or throw an exception.
To add a new Handler to the chain, the coder would go to the last element of the chain and tell it there was a new element. To do something, he'd just call handleRequest on the first element of the chain.

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

To solve this problem, I suggested using a different approach.
I'd have a base "Handler" class as well, with "Handler1", "Handler2", just like the previous method mentioned.
However, there would be no "getSuccessor" method. Instead, I'd have a Collection class with a list of handlers(a Vector, an ArrayList, or whatever is best in this case).
The handleRequest function would still exist, but it wouldn't propagate the call to the next handlers. It would just process the request or return null.
To handle a request, one would use

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());".

Or, to prevent code duplication, a "parseRequest(request)" method could be added to the collection class. To add a new handler, one would go to the collection constructor(or static{} block, or something equivaleng) and simply add the code "addHandler(new Handler3());".

这种方法我确实缺少责任链的哪些优势?哪种方法最好(假设 是最好的方法)?为什么?每种设计方法都可能导致哪些潜在的错误和问题?

Exactly what advantages of chain-of-responsibility am I missing with this approach? Which method is best(assuming there is a best method)? Why? What potential bugs and issues can each design method cause?

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

For those who need context, here is what the original code looked like:

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

推荐答案

与集合的继承者相比,我更喜欢您的集合思想.操作这组处理程序非常简单明了:collections接口是众所周知的,每个人都知道如何遍历List或不遍历List.

I like your idea with collection better than those successors. It makes it easy and clear to manipulate this set of handlers: the collections interface is well known and everybody understands how to iterate over a List or what not.

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

If you use this successor way suggested by a friend, take care not to fall into a very deep recursion (unless your platform supports tail calls, I don't know if JVMs are capable of that).

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

I wouldn't recommend adding any methods to the collection. You get much more complicated design that's harder to comprehend and harder to modify. There are two separate concerns: storing a set of handlers and the interpretation of this handlers as a chain of responsibility. A method that handles requests by iterating over a collection is on higher level of abstraction than collection housekeeping methods, therefore shouldn't belong to collection interface.

这篇关于责任链与类别列表相比有什么优势?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆