锁定老帖子 主题:请问责任链真的是一种设计模式吗
精华帖 (2) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-07-27
ahuaxuan 写道 虚函数和MFC是c++的东西吧,包括这个名词(虚函数)我都不知道应该怎么理解(c++我早还给老师了)。 虚函数就是可以体现多态的函数。简单地说,JAVA中的所有方法都是虚函数。 ahuaxuan 写道 很显然阎宏的书是用java语言的,你看他对责任链的描述和gof的描述是一样的吗? 我觉得不用那么强调概念上的东西,能灵活运用就行了。 每个模式都说明了解耦和通过结构来保证约束的思想。 能明白这点就OK了。 |
|
返回顶楼 | |
发表时间:2007-07-27
首先不太明白搂主为什么总是拿structs 1.0 做例子呢?
有时候业务层一些解决方式和 structs 1.0 有直接的关系吗? 其次,责任链是否是一个模式很重要吗? |
|
返回顶楼 | |
发表时间:2007-07-27
netpcc 写道 我觉得不用那么强调概念上的东西,能灵活运用就行了。
这一点我非常同意,所以我其实是在有意模糊责任链这个概念,为的就是想说明责任链可以被灵活的实现。 yananay 写道 首先不太明白搂主为什么总是拿structs 1.0 做例子呢?
有时候业务层一些解决方式和 structs 1.0 有直接的关系吗? 其次,责任链是否是一个模式很重要吗? 因为struts1.x没有拦截器啊,但是我记得有一个额外的框架可以作补充,让struts拥有拦截器。 yananay 写道 其次,责任链是否是一个模式很重要吗?
责任链是否是一个模式不重要,但是否理解它就比较重要了 |
|
返回顶楼 | |
发表时间:2007-07-27
因为struts1.x没有拦截器啊,但是我记得有一个额外的框架可以作补充,让struts拥有拦截器。
那你应该说责任链模式应用于 structs1.x 的拦截器方式。 |
|
返回顶楼 | |
发表时间:2007-07-27
说一下我的想法
您的第一种职责链,即所称的 基本版责任链,我觉得更是装饰器Decorator模式的一种应用。在你的代码示例中,每一种Filter在调用后面的Filter前后都做了一下额外的操作,虽然只是System.out;而职责链的目标是分离请求的调用者和接收者,虽然请求可以沿着链传递,但是逻辑上应该只有一个接收者对其处理。 您的第二种职责链,即所称的 混血版责任链,和netpcc等的观点一致,就是一个实现功能操作的改版的观察者实例 您的第三种职责链,与原本的职责链相比,其实是将原来的一个类(包括处理和传递下一个的功能),分成了三个类——处理类、链类和配置类,这样修改后可能在极端的环境下有其好处,但在一般的情况下确明显的增加了程序设计的复杂度,而且你的Chain和handler的处理方法内的互相调用,即ConcreateHandlerChain中的 if (firstElement < handlerConfigs.length) { if (handlerConfigs[firstElement].getPattern().matcher(doRegex).matches()) { [b]handlerConfigs[firstElement].getHandler().executeHandler(this); [/b] } else { this.executeHandler(); } } 和ConcreateHandler中的 public void executeHandler(HandlerChain handlerChain){ System.out.println("1----------check the user in this filter!"); [b]handlerChain.executeHandler(); [/b] System.out.println("2----------check the user in this filter!"); } 互相交叉,有违单向依赖法则 另,是不是可以作下面重构,不知有没有影响代码的意图。将 ++firstElement; if (firstElement < handlerConfigs.length) { if (handlerConfigs[firstElement].getPattern().matcher(doRegex).matches()) { handlerConfigs[firstElement].getHandler().executeHandler(this); } else { this.executeHandler(); } } 改写成 for (firstElement = 0; firstElement < handlerConfigs.length; firstElement++) { if (handlerConfigs[firstElement].getPattern().matcher(doRegex).matches()) { handlerConfigs[firstElement].getHandler().executeHandler(this); return; } } |
|
返回顶楼 | |
发表时间:2007-07-27
设计模式应该是以Gof为基础的,如果楼主要讨论责任链是否属于设计模式,那本书里写的都是设计模式。
|
|
返回顶楼 | |
发表时间:2007-07-27
ahuaxuan 写道 阎宏那本书里是这样描述的: 在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成的一条链。请求在这个链上传递,知道链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。 我觉得不是很准确 阎宏的书的确不准确,还是要看Gof |
|
返回顶楼 | |
发表时间:2007-07-27
qinysong 写道 说一下我的想法
您的第一种职责链,即所称的 基本版责任链,我觉得更是装饰器Decorator模式的一种应用。在你的代码示例中,每一种Filter在调用后面的Filter前后都做了一下额外的操作,虽然只是System.out;而职责链的目标是分离请求的调用者和接收者,虽然请求可以沿着链传递,但是逻辑上应该只有一个接收者对其处理。 您的第二种职责链,即所称的 混血版责任链,和netpcc等的观点一致,就是一个实现功能操作的改版的观察者实例 您说得不错,这两种方式其实都是用其他模式来实现所谓得责任链,这也是我认定观察者不是设计模式的原因。 qinysong 写道 您的第三种职责链,与原本的职责链相比,其实是将原来的一个类(包括处理和传递下一个的功能),分成了三个类——处理类、链类和配置类,这样修改后可能在极端的环境下有其好处,但在一般的情况下确明显的增加了程序设计的复杂度,而且你的Chain和handler的处理方法内的互相调用,即ConcreateHandlerChain中的 if (firstElement < handlerConfigs.length) { if (handlerConfigs[firstElement].getPattern().matcher(doRegex).matches()) { [b]handlerConfigs[firstElement].getHandler().executeHandler(this); [/b] } else { this.executeHandler(); } } 和ConcreateHandler中的 public void executeHandler(HandlerChain handlerChain){ System.out.println("1----------check the user in this filter!"); [b]handlerChain.executeHandler(); [/b] System.out.println("2----------check the user in this filter!"); } 互相交叉,有违单向依赖法则 单向依赖法则是指什么呢,好像面向对象设计的原则里好像没有关于单向依赖的描述呀。 qinysong 写道 另,是不是可以作下面重构,不知有没有影响代码的意图。将 ++firstElement; if (firstElement < handlerConfigs.length) { if (handlerConfigs[firstElement].getPattern().matcher(doRegex).matches()) { handlerConfigs[firstElement].getHandler().executeHandler(this); } else { this.executeHandler(); } } 改写成 for (firstElement = 0; firstElement < handlerConfigs.length; firstElement++) { if (handlerConfigs[firstElement].getPattern().matcher(doRegex).matches()) { handlerConfigs[firstElement].getHandler().executeHandler(this); return; } } 如果这样重构,导致的结果就是只要链上一某个不符合,那调用就结束(所有的方法依次出栈),这并不是我的目标,我是想如果有一个责任不符合,那么就继续执行链上的下一个责任,直到链尾为止,到达链尾后所有的方法依次出栈。 |
|
返回顶楼 | |
发表时间:2007-07-27
Decorator模式是结构模式,体现的是结构特点。
职责链是,行为模式的一种,是从他的行为上来分析。 职责链和Decorator模式通常是同一事物的两方面。 qinysong的改法很不好。 首先这种改法破坏了Observer的一旦有事件发生,所有监听者都应该收到通知的原则。因此已经不能算Observer模式了。 作为职责链模式来说,他又丧失了各个组建间的协作性。 比如说对于URL的解码来说,可以由类A来完成域名部分的IDN解码,由类B来完成路径部分的16进制的解码。16进制解码可以按照各种不同的编码方式来选择。 至于交叉引用的问题,只需要将事件本身和事件到处理器的映射分成2个类就可以了。 |
|
返回顶楼 | |
发表时间:2007-07-27
ahuaxuan 写道 qinysong 写道 另,是不是可以作下面重构,不知有没有影响代码的意图。将 ++firstElement; if (firstElement < handlerConfigs.length) { if (handlerConfigs[firstElement].getPattern().matcher(doRegex).matches()) { handlerConfigs[firstElement].getHandler().executeHandler(this); } else { this.executeHandler(); } } 改写成 for (firstElement = 0; firstElement < handlerConfigs.length; firstElement++) { if (handlerConfigs[firstElement].getPattern().matcher(doRegex).matches()) { handlerConfigs[firstElement].getHandler().executeHandler(this); return; } } 如果这样重构,导致的结果就是只要链上一某个不符合,那调用就结束(所有的方法依次出栈),这并不是我的目标,我是想如果有一个责任不符合,那么就继续执行链上的下一个责任,直到链尾为止,到达链尾后所有的方法依次出栈。 不好意思,上面的代码我没有实际的编译一下,其实你想要的效果就是HandlerChain的executeHandler方法,会调用一个符合条件的Handler对象进行处理,如果下标firstElement处的Handler不符合规则,就探索下一个,直至遍历到一个符合的为止(如果存在的话)。 所以上面的重构代码,只需把firstElement 放到上面即可,如下所示,已通过测试,和你的效果一样 firstElement += 1; for (; firstElement < handlerConfigs.length ; firstElement++) { if (handlerConfigs[firstElement].getPattern().matcher(doRegex).matches()) { handlerConfigs[firstElement].getHandler().executeHandler(this); return; } } 单向依赖法则是我从无环依赖原则(ADP)推演的,ADP表达包和包之间不能存在相互依赖,包是一种实体,而类也是一种实体,只不过小于包实体,所以类之间虽然在特殊的情况下不能避免循环依赖,但只要可能最好还是避免,这样得到的设计会更简单、更清晰和容易理解 netpcc 写道 Decorator模式是结构模式,体现的是结构特点。
职责链是,行为模式的一种,是从他的行为上来分析。 职责链和Decorator模式通常是同一事物的两方面。 将模式分类为结构型模式 或行为型模式,并不是对于同一事物,主观上从不同的角度去观察得到的,而是看这个模式客观上主要解决哪方面的问题,结构型模式解决类和对象之间组合问题,行为型模式解决行为分配的问题,当然这也含有一个侧重的问题,比如结构型中也有行为分配的成分,行为型中也有类或对象组合的成分。 职责链和Decorator模式决不是同一事物的两个方面。 职责链的意图通过一条候选对象链隐式的向一个对象发送请求,从而弱化请求的发送者和接收者之间的耦合关系;Decorator的意图是动态的给对象添加额外的职责,比如jdk中的输入输出流类,在最基本的字节流基础上,具有各种装饰器,通过这些装饰器,为最基本的流增加各种额外功能或修饰,比如增加内存缓冲和数据类型等,这样就应该很好理解和职责链的区别 |
|
返回顶楼 | |