Struts2中的设计模式
http://blog.csdn.net/significantfrank/article/details/7712053
1. Command Pattern
基本定义: 把Command(Request)封装成对象,把发出命令(Invoker)的责任和执行命令(Receiver)的责任分割开,委派给不同的对象。

责任划分有什么好处?
责任约单一,内聚性越高,可重用的可能性越大,试想下,如果服务员不仅要点菜,还要去做菜,会是什么情景。
为什么把Invoker和Receiver解耦好处多?
类之间的耦合越低,可扩展的可能性越高。解耦后,更换一个服务员并不会影响厨师的工作
那么把Request封装成对象具体是什么意思呢?
在遥控器Remote Control例子中,比如我有一个‘开灯’的Request,那么就应该对应有一个LightOnCommand对象,关灯就应该有LightOffCommand
在Web应用中,我有一个add user的Request,那么就应有一个AddUserCommand去处理请求, 或者用struts的name convention就是AddUserAction.
那么在Struts中又是怎么运用Command Pattern的呢?
Client : FilterDispatcher Servlet
Invoker: ActionInvocation
Command: Action (not a must in Struts2)
ConcreteCommand:AddUserAction
Receiver: ServiceImpl (not a must, depends how many logic you want to put into concreteCommand)
Struts,你什么时候调用的setCommand()?
用户定义了Action Mapping在struts.xml里,在web container启动时,ConfigurationManager 就装载了struts.xml,当Request过来时,Struts Framework会根据当前的URL去找ConfigurationManager所对应的concreteCommand/Action, 然后这个Action会被set到ActionInvocation
Command Interface是必须的吗?
在struts1中,有一个Interface,所有的Action都必须是它的实现。但是在Struts2中,Action可以是任意的POJO,因为在Runtime的时候,具体的Action是什么,该调用它的什么方法,都可以通过配置文件(MetaData)+ Java Reflection来实现。这种新方式的好处是POJO Action没有了对框架的依赖,测试将会更加容易。缺点是因为没有interface的约束,调用Action的什么方法完全取决于默认值(比如execute)或是配置文件中的配置。若设置不妥,只有在Runtime的时候才能发现错误。
Receiver 是必须得吗?
不是,取决于你Action的厚度,如果你想让Action很轻的话,那么通常你会在Action中使用UserService.addUser()去做事情,此时的UserService就是Receiver。把Action设计的厚点,直接把addUser的logic放在Action中也是可以的。
Struts2中运用了command的思想,但并没有严格的按照其经典模型实现,而是做了些变通,这些变通乍看起来可能是有点违背设计原则,比如说取消了Action Interface,这不是反模式吗,反面向接口的编程吗,但仔细想想,这里我们真的需要这个接口吗?通过配置文件+Reflection,我们同样可以做到在Runtime的时候给ActionInvocation注入不同的Action的目的。而接口却增加了用户实现对框架的依赖,降低了程序的可测性,所以这样的变通其实是有积极意义的,虽然我们损失了一点点接口作为契约所带来的好处。
2. Interceptor Pattern
于其说这是模式,不如说这是AOP和Pipeline思想的结合,只不过Struts2中的实现非常的精巧,我不得不说这应该作为一个模式来推广。
AOP : 所谓的AOP就是preProcess and postProcess, 系统应用中,许多地方是需要面向切面的,比如log,authentication,etc...。看过一些实现,如Java Dynamic,但不够优雅。
Pipeline:分层就是把复杂的问题分层多个层次,每一层只处理问题的一小部分。通信的7层模型就是典型的范例
Interceptor Pattern 不仅为系统进行分层,而且还提供了AOP的处理,此外,还以一种plug-in的方式为用户提供了无限扩展的可能。
应该怎么实现?
Interceptor的调用过程类似于一个栈式调用,所以想到递归是很自然的,这既避免了像Dynamic Proxy那样的hack,又提供了更好的扩展性。
还是以Struts中的类作为例子,其类图如下:
调用过程:
Pseudo 代码:
ActionInvocation
- public Result invoke(){
- if( interceptors.hasNext() ){
- Interceptor interceptor = interceptors.next();
- result = interceptor.intercept(this);
- }
- else {
- action.execute();//如果没有更多的Interceptor,停止递归,调用action
- }
- }
public Result invoke(){
if( interceptors.hasNext() ){
Interceptor interceptor = interceptors.next();
result = interceptor.intercept(this);
}
else {
action.execute();//如果没有更多的Interceptor,停止递归,调用action
}
}
InterceptorImpl
- public SomeInterceptor implements Interceptor{
- public Result intercept(ActionInvocation actionInvocation){
- //pre-processing
- // 递归调用
- result = actionInvocation.invoke();
- //post-processing
- return result;
- }
- }
public SomeInterceptor implements Interceptor{
public Result intercept(ActionInvocation actionInvocation){
//pre-processing
// 递归调用
result = actionInvocation.invoke();
//post-processing
return result;
}
}
More: http://www.cnblogs.com/west-link/archive/2011/06/22/2086591.html
http://bosy.dailydev.org/2007/04/interceptor-design-pattern.html
Struts2 架构图
Struts 2 framework: http://viralpatel.net/blogs/introduction-to-struts-2-framework/
Struts2中的设计模式的更多相关文章
- 【转】Struts2的线程安全 和Struts2中的设计模式----ThreadLocal模式
[转]Struts2的线程安全 和Struts2中的设计模式----ThreadLocal模式 博客分类: 企业应用面临的问题 java并发编程 Struts2的线程安全ThreadLocal模式St ...
- Struts2中的设计模式----ThreadLocal模式
http://www.cnblogs.com/gw811/archive/2012/09/07/2675105.html 设计模式(Design pattern):是经过程序员反复实践后形成的一套代码 ...
- struts2中的拦截器
一 AOP思想: 面向切面编程的思想 AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP ...
- 07. struts2中对Action的管理方式
web.xml配置文件的常用代码 <filter> <filter-name>struts2</filter-name> <filter-class>o ...
- struts2中从后台读取数据到<s:select>
看到网上好多有struts2中从后台读取数据到<s:select>的,但都 不太详细,可能是我自己理解不了吧!所以我自己做了 一个,其中可能 有很多不好的地方,望广大网友指出 结果如图 p ...
- struts2中各个jar包作用
Struts2.3.4 所需的Jar包及介绍 Jar包的分类 jar包名称 jar包版本 jar包 文件名 jar包 的作用 jar包内包含的主要包路径及主要类 依赖的自有jar包名称 依赖的第三方j ...
- Struts2中Date日期转换的问题
今天跑程序的时候莫名其妙的出现了下面的一个异常: java.lang.NoSuchMethodException:com.ca.agent.model.mybatis.ApprovalInforC ...
- struts2中的jar包
核心包: (后面数字是版本号,不同struts2版本,数字可能不一样.) struts2-core-2.1.8.1 struts2的核心jar包,不可缺少的 xwork-core-2.1.6 xwor ...
- Struts2中的EasyUI
Struts2中的EasyUI 一.easy UI是类似于jQuery UI的插件库,它提供了丰富的各种常用插件:tree.datagrid... tree插件: 语法:$(selector).tre ...
随机推荐
- UIView显示时遮挡导航栏的方法
[self.navigationController.view:addSubview];
- hdu 1233 还是畅通工程 (最小生成树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1233 还是畅通工程 Time Limit: 4000/2000 MS (Java/Others) ...
- Java多线程学习(二)synchronized关键字(2)
转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79670775 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...
- java解析XML之DOM解析和SAX解析(包含CDATA的问题)
Dom解析功能强大,可增删改查,操作时会将XML文档读到内存,因此适用于小文档: SAX解析是从头到尾逐行逐个元素解析,修改较为不便,但适用于只读的大文档:SAX采用事件驱动的方式解析XML.如同在电 ...
- mysql where/having区别
mysql> select 2-1 as a,password from mysql.user where user='root' having a>0; +---+----------- ...
- 网络知识===wireshark抓包出现“TCP segment of a reassembled PDU”的解释(载)
网上胡说八道,众说风云,感觉这篇还算靠谱点. 原文链接:http://blog.csdn.net/dog250/article/details/51809566 为什么大家看到这个以后总是会往MSS, ...
- nodejs 优雅的连接 mysql
1.mysql 及 promise-mysql nodejs 连接 mysql 有成熟的npm包 mysql ,如果需要promise,建议使用 promise-mysql: npm:https:// ...
- Jmeter接口测试示例
如果是Web,需要使用badboy进行录制,今天讲的是接口,因此可以不用录制. (1)新建测试计划 (2)添加http请求默认值 (3)添加http信息头管理器 (4)添加token的正则表达式:&q ...
- javascript 实现图片拖动
javascript实现图片拖动效果并不难,主要的思路如下 1:给图片绑定监听鼠标按下对象,设置拖动属性为true 2:鼠标抬起:拖动属性为false 鼠标移动:改变坐标即可,新坐标=图片原始坐标+鼠 ...
- linux命令(5):netstat命令
网络监控:netstat –in [显示所有配置接口的状态] 查看端口状态:netstat -anlp | grep 8080 [显示8080端口列出的监听状态] 查看某个进程软件名:netstat ...