复合模式不是说把几个模式组合在一起就叫复合模式, 而是组合在一起后真正产生意义, 形成解决一类问题的模板
-
(1) MVC模式包含视图、控制器、模型
用户和视图交互;
用户对视图做某件事情时, 视图告诉控制器;
控制器要求模型改变状态;
控制器也可能要求视图做出改变(例如某个按钮置灰);
模型状态改变时, 会通知视图;
视图也可以向模型询问状态
(2) 视图和控制器之间使用了策略模式;
控制器提供了策略, 视图检测到用户操作后, 都委托给关联的控制器处理;
(3) 视图内部使用了组合模式
每个显示的组件, 不是组合节点就是叶结点
(4) 模型和视图之间使用了观察者模式
视图注册在模型中, 模型发生状态变化时, 会通知关联的视图
(5) 示例
有点长, 直接看"headfirst.designpatterns.mvc.djview"的示例代码吧
-
MVC与Web
(1) 过程
浏览器发出HTTP请求, 对应于一个Servlet;
Servlet扮演控制器;
JSP扮演视图;
控制器将控制权交给视图;
视图通过HTTP返回给浏览器
(2) 示例
DJViewServlet.java
public class DJViewServlet extends HttpServlet { private static final long serialVersionUID = 2L; public void init() throws ServletException { BeatModel beatModel = new BeatModel(); beatModel.initialize(); getServletContext().setAttribute("beatModel", beatModel); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { BeatModel beatModel = (BeatModel) getServletContext().getAttribute("beatModel"); String bpm = request.getParameter("bpm"); if (bpm == null) { bpm = beatModel.getBPM() + ""; } String set = request.getParameter("set"); if (set != null) { int bpmNumber = 90; bpmNumber = Integer.parseInt(bpm); beatModel.setBPM(bpmNumber); } String decrease = request.getParameter("decrease"); if (decrease != null) { beatModel.setBPM(beatModel.getBPM() - 1); } String increase = request.getParameter("increase"); if (increase != null) { beatModel.setBPM(beatModel.getBPM() + 1); } String on = request.getParameter("on"); if (on != null) { beatModel.on(); } String off = request.getParameter("off"); if (off != null) { beatModel.off(); } request.setAttribute("beatModel", beatModel); RequestDispatcher dispatcher = request.getRequestDispatcher("/djview.jsp"); dispatcher.forward(request, response); } }
DJViewServlet是控制器, 在init()方法中加入一个JavaBean对象beatModel, 这个对象其实就是模型Model;
每当有请求到来时, Servlet会分析其中的各个参数, 然后调用beatModel的set方法, 更改模型;
然后这个更新后的模型会被set到request域中, 传给jsp并做重定向;
request.setAttribute("beatModel", beatModel); RequestDispatcher dispatcher = request.getRequestDispatcher("/djview.jsp"); dispatcher.forward(request, response);
djview.jsp
<jsp:useBean id="beatModel" scope="request" class="headfirst.designpatterns.mvc.djview.BeatModel" /> <html> <head> <title>DJ View</title> </head> <body> <h1>DJ View</h1> Beats per minutes = <jsp:getProperty name="beatModel" property="BPM" /> <br /> <hr> <br /> <form method="get" action="/servlet/DJViewServlet"> BPM: <input type=text name="bpm" value="<jsp:getProperty name='beatModel' property='BPM' />"> <input type="submit" name="set" value="set"><br /> <input type="submit" name="decrease" value="<<"> <input type="submit" name="increase" value=">>"><br /> <input type="submit" name="on" value="on"> <input type="submit" name="off" value="off"><br /> </form> </body> </html>
在这个jsp文件中首先关联一个作用域为request的BeatModel对象, 然后再需要用到的地方用jsp:getProperty获取, property和BeatModel的内部域对应
(3) 对于Web版的MVC模式, 最大的区别是视图不再作为模型的观察者, 这是因为对于Web应用, 随时的通知是没有意义的, 只有当页面被创建和返回时, 才需要创建视图和返回模型;
另一个区别是策略对象虽然还是作为控制器的Servlet, 但是和视图的绑定是靠URL实现的
有时, 模型不能恰好满足我们的需求, 这时可以考虑用适配器模式匹配它们
chapter12_复合模式——MVC
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 本章内容: 映射请求到Spring控制器 透明地绑定表单参数 校验表单提交 状态管理、工作流以及验证都是Web 开...
- SpringMVC介绍 Spring web mvc 和Struts2都属于表现层的框架,它是Spring框架的一...