原文链接:http://www.hechunchen.info/?p=17
最近看到Design Patterns的Chain of Responsibility(职责链模式),印象最深的一点是Client的请求会沿着一条链往后走。非常像Openfire里边处理客户端的packet的过程(也是有一条链存在的)。那么openfire到底有没有用到职责链模式呢?
我带着疑问,重温了一下openfire处理packet的过程。
可以看到StanzaHandler.process(Element doc)中,对于包的处理其实被分成了3条线。并不是我们预想中的只有“职责链”这1条链。在process函数的代码中,只用了if …else if…else if…就完成了IQ/Message/Presence三种包的分发。
好了,我们现在知道openfire没有用到“职责链模式”了。那么,如果想用上我们刚学习的这个模式,应该怎么用呢?我们知道Chain of Responsibility的含义是:很多对象都有机会处理请求。我们把这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。思路如下:
目前,IQ/Message/Presence三种包的处理部分现在是“并行”的。那么,我们把它们改为“串行”的,让他们排着队来处理进来的packet。进来的packet,我们首先丢进IQ的处理程序中,处理程序判断packet是否为IQ包,如果是则处理,否则,丢给Message的处理程序。Message的处理程序判断packet是否为Message包,如果是,说明这是自己的职责范围内的事儿,处理,否则,丢给Presence的处理程序。Presence的处理程序继续做判断。
那,是不是代表Openfire有可以改进的空间呢?
这里必须提到职责链模式的不足之处:对于每一个请求都需要遍历职责链,性能是个大问题。而且openfire中的条件分支较少。openfire不采用此模式,也是很能理解的。
但是如果条件分支过多,或者,逻辑复杂的时候,可以考虑用职责链模式来解耦,会让代码具有更好的扩充性。
写到这里,突然想起,大三上那个WJJ的项目中,我给2行4列陈列柜里的任2张图片中添加标注时,需要判断两张图片的位置关系,我写了很多很多if…else…在很多if里边还嵌套了if…else…,当时判断语句里边直接就写上了处理逻辑。整个判断分支达到了500+行代码。╮(╯▽╰)╭都怪那时没有学好设计模式,用责任链模式挺好的,在那里。明显的代码坏味道,程序虽然能够跑,但是代码结构真是稀烂。……菜鸟也是需要时间成长的吧。
最后一句话总结一下Chain of Responsibility:链上行走,寻找承担职责的那个人。