TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
MVC是Xerox PARC在八十年代为编程语言Smalltalk发明的一种软件设计模式,至今已被广泛使用。最近几年被推荐为Sun公司J2EE平台的设计模式。 MVC模式是"Model-View-Controller"的缩写,中文翻译为"模式-视图-控制器"。MVC应用程序总是由这三个部分组成。
随着网络应用的快速增加,MVC模式对于Web应用的开发是一种非常先进的设计思想,无论你选择哪种语言,无论应用多复杂,它都能为你理解分析应用模型时提供最基本的分析方法,为你构造产品提供清晰的设计框架,为你的软件工程提供规范的依据。
视图(View)代表用户交互界面,对于Web应用来说,可以概括为HTML界面,但有可能为XHTML、XML和Applet。随着应用的复杂性和规模性,界面的处理也变得具有挑战性。一个应用可能有很多不同的视图,MVC设计模式对于视图的处理仅限于视图上数据的采集和处理,以及用户的请求,而不包括在视图上的业务流程的处理。
控制(Controller)可以理解为从用户接收请求, 将模型与视图匹配在一起,共同完成用户的请求,在许多设计中在这里应用了适配器模式。划分控制层的作用也很明显,它清楚地告诉你,它就是一个分发器或者说是选择器,选择什么样的模型,选择什么样的视图,可以完成什么样的用户请求。控制层并不做任何的数据处理。例如,用户点击一个连接,控制层接受请求后, 并不处理业务信息,它只把视图层传过来的用户的信息传递给模型,告诉模型做什么,选择符合要求的视图返回给用户。因此,一个模型可能对应多个视图,一个视图可能对应多个模型。
模型(Model):就是业务流程/状态的处理以及业务规则的制定。业务流程的处理过程对其它层来说是黑箱操作,模型接受来自由Controller处理选择转发视图请求的数据,并将处理结果通过Controller转发或直接返回给视图层。业务模型的设计可以说是MVC最主要的核心。在J2EE平台中主要是由EJB和javaBean来实现。对于开发人员来说可以不管视图的设计,这样就可以专注于业务模型的设计。
MVC的优点
MVC设计模式的应用模型是按一定的规则抽取出来,抽取的层次很重要,这也是判断开发人员是否优秀的设计依据。抽象与具体不能隔得太远,也不能太近。MVC并没有提供模型的设计方法,而只告诉你应该组织管理这些模型,以便于模型的重构和提高重用性。我们可以用对象编程来比喻,MVC定义了一个顶级类,告诉它的子类你只能做这些,但没法限制你能做这些。这点对编程的开发人员非常重要。模型、视图与控制器的分离,使得一个模型可以具有多个显示视图。如果用户通过某个视图的控制器改变了模型的数据,所有其它依赖于这些数据的视图都应反映到这些变化。因此,无论何时发生了何种数据变化,控制器都会将变化通知所有的视图,导致显示的更新。由于一个应用被分离为三层,因此有时改变其中的一层就能满足应用的改变。一个应用的业务流程或者业务规则的改变只需改动MVC的模型层。
MVC的缺点
MVC的不足体现在以下几个方面:
(1)增加了系统结构和实现的复杂性。对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。
(2)视图与控制器间的过于紧密的连接。视图与控制器是相互分离,但确实联系紧密的部件,视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了他们的独立重用。
(3)视图对模型数据的低效率访问。依据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据。对未变化数据的不必要的频繁访问,也将损害操作性能。
(4) 目前,一般高级的界面工具或构造器不支持MVC模式。改造这些工具以适应MVC需要和建立分离的部件的代价是很高的,从而造成使用MVC的困难。
MVC在系统中的应用
在系统中,JSP充当是View角色,Servlet充当是Controller角色,JavaBean充当是Model角色。Servlet来分发客户端浏览器的请求,就相当于是系统中数据传递中的方向标。在视图层中html或者JSP中的表单中提交用户请求,通过请求名在web.xml配置文件找到与用户请求相对的应的Servlet类,每个Servlet都有一个特定的Servlet对象与之对应,如果这个Servlet已在服务器容器当中,就调用Servlet的Service方法,如果不存在就加载对应的Servlet类,再在Servlet类里的Service方法里面去调用相应业务逻辑处理的JavaBean完成业务逻辑的处理和对数据库的访问。
MVC示例
例如在本系统中登录的MVC实现示例:
1.登录页面,即MVC里的视图,用于获取用户登录信息
<form action="login.do" method="post" name="login_form" id="login_form" onsubmit="return isValid();">
//action="login.do"就是表示由在web.xml里面相对应的Servlet类来处理。
<table>
<tr>
<td>ID:</td>
<td><input type="text" name="id" size="20"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td><input name="type" type="radio" value="1" checked>学生</td>
<td><input type="radio" name="type" value="2">老师</td>
<td><input type="radio" name="type" value="3">管理员</td>
</tr>
<tr>
<td> <input type="submit" value="登 陆" name="ok"></td>
<td><input type="reset" value="重 置" name="cancel"></td>
</tr>
</table>
</form>
2.在web.xml配置如下:
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>cn.edu.xtu.xg2b.servlet.LoginServlet</servlet-class>
//最终找到的处理类
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
//由LoginServlet对应的Servlet来处理
<url-pattern>/login.do</url-pattern>
</servlet-mapping>
3.LoginServlet类继承于HttpServlet,实现Controller,即MVC里的控制层。
package cn.edu.xtu.xg2b.servlet;
public class LoginServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取视图层传过来的用户信息
HttpSession session=request.getSession();
String id=request.getParameter("id");
String password=request.getParameter("password");
String type=request.getParameter("type");
int Utype = Integer.parseInt(type);
User user=User.getInstanse(id,password,Utype);//创建JavaBean对象
if(user.doLogin()){//调用JavaBean里的doLogin()方法完成验证逻辑。
session.setAttribute("user", user);
//选择显示页面
if(Utype==1){
session.setAttribute("logined", "student");
RequestDispatcher dispatcher=request.getRequestDispatcher("/studentjsp/studentM.jsp");
dispatcher.forward(request, response);}
else if(Utype==2){
session.setAttribute("logined", "teacher");
RequestDispatcher dispatcher= request.getRequestDispatcher("/teacherjsp/teacherM.jsp");
dispatcher.forward(request, response);}
else if(Utype==3){
session.setAttribute("logined", "admin");
RequestDispatcher dispatcher= request.getRequestDispatcher("/adminjsp/adminM.jsp");
dispatcher.forward(request, response);}
}
else{
RequestDispatcher dispatcher= request.getRequestDispatcher("/errorlogin.html");
dispatcher.forward(request, response);
}
}
}
4.JavaBean类doLogin方法
package cn.edu.xtu.xg2b.beans;
public class User {
protected String id;
protected String name;
protected String password;
protected String qq;
protected String Email;
......
//省略get和set方法
//根据用户类型获取用户对象
public static User getInstanse(String id,String password,int type){
if(type==1)
return new Student(id,password);
else if(type==2)
return new Teacher(id,password);
else if(type==3)
return new Admin(id,password);
else return null;
}
// 用户验证
public boolean doLogin() {
return false;
}
}
//各种用户类型的JavaBean可以分别继承了User的JavaBean这个父类,覆盖了doLogin()方法,实现了自己的验证逻辑。
|
|