MVC小结



 
一 . MVC概述:

最近才接触到它,M—V—C,顾名思义,即模型层(数据库控制层,进行逻辑处理因此也可以分为Dao层和Service层),视图层(请求到的Jsp/Servlet,Html),控制层(一般是一个Servlet,现在多用Structs的实现 )。MVC设计模式它的目的是实现一种动态的程序设计,使后续的对程序的修改和扩充套件简化,并且使程序可重用一部分代码。MVC还是程序的结构更加简化清晰,不同专长的人可以完成不同的功能:



 


视图:界面设计人员进行界面设计(系美工)
控制器:负责转发请求,对流程进行控制,它主要用来实现视图层和模型层同步处理。
模型:要处理很多业务逻辑
MVC结构的系统会从根本上强制我们将web系统中的数据对象、业务逻辑、用户界面三者分离
二 . MVC设计模式的实现流程:定义了一 个简单的实现流程



 
 


用一个简单的MVC实例实现:




  •  
     

    我们的MVC理框架结构有五部分组成:
    1. ControllerServlet.java:请求分发控制器,解析请求中的动作名字,调用动作工厂对象生成的动作对象处理请求,处理后返回的结果为目地url,控制器再将请求和应答对象转向目标url。
    2. ActionFactory.java:该工厂类将请求中的动作名转换成 servlet 可以用来完成其工作的动作类。
    3. Action.java: 接口类,该接口定义所有动作的公共接口。
    4. 具体Action的实现类:指实现了Action接口的类,会被ActionFactory工厂根据请求中的名字创建,从而调用其具体实现的方法处理Request\Response对象后,返回一个URL由主控Servlet转发给用户。可以理解为,为一个具体的Action实现类用于处理页面上每一种用户点击(请求)
    5. 系统视view层e实现:
    代码说明各部分的简单实现:
    (1).控制器Servlet实现:
    所有页面发起的以*.cn的请求,都被web.xml配置给ControllerServlet进行处理,在ControlServlet中根据*的字符串,调用ActionFactory生成的指定Action对象的方法,再将处理后的URL转发给用户。
    控制器Servlet代码模型如下:
    package cn.netjava.servlet;
    import java.io.IOException;
    import javax.servlet.*;
    import cn.netjava.action.Action;
    import cn.netjava.action.ActionFactory;
    /**

    *系统控制器实现
    *功能:1.解析请求中的命令名
    *      2.根据请求的命令名调用工厂对象创建命令处理对象
    *      3.调用命令对象处理请求和应答对象,返回目标路径名
    *      4.本控制器将请求和应答转发至目标路径名
    */
    public class ControlServlet extends HttpServlet {
          //主控servlet分发用户请求的入口
         public void   service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
             try{ 
    String path=
    String start=path.getsubString();
    String end=path.getsubString();
    String actionName=
        //得到请求的命令名字:解析出*.cn请求中*所指代的字符串,即动作名字
            String actionName= getActionName(request);
            System.out.println(" request action is: "+actionName);
                //根据请求的动作名,得到控制器servlet中配置的Action实现类名字
              String actionClassName=this.getInitParameter(actionName);
              System.out.println("actionClassName is: "+actionClassName);
               //通过工厂类创建命令对象
              Action action = ActionFactory.getIns().getAction(actionClassName);
                //使用动作对像处理动作,返回结果为处理后要输出的目标页面
              String url = action.execute(request, response);
              if (url != null){
                //输出目标页面
              System.out.println("dest url is: "+url);
              getServletContext().getRequestDispatcher(url).forward(request, response);
               }
             }catch(Exception ef){
            ef.printStackTrace();
            //出错时,输出到错误页面
       getServletContext().getRequestDispatcher("/error.jsp").forward(request, response);
             }
    }
    //解析得到请求中的"命令"字
    //如请求路径为loginAction.cn解析得到loginAction
         protected String getActionName(HttpServletRequest request) {
              String path = request.getServletPath();
              return path.substring(1, path.lastIndexOf("."));
         }
    }
    (2).Action对象工厂类实现:
    ActionFactory是一个单实例类(整个系统只需要使用其一个对象),它只提供一个Action getAction(String actionClass) 的方法调用;这个方法根据传入的类名字(实现了Action接口的类名字)创建一个Action对象。这个方法在ControlServlet中被调用。代码如下:
    package cn.netjava.action;
    /**
    *命令对象工厂类实现
    *根据命令名字,创建命令对象
    */
    public class ActionFactory {
        //单实例访问方法
        public static ActionFactory getIns(){
        if(null==ac){
        ac=new ActionFactory();
        }
        return ac;
        }

        /**
         * 根据具体的Action类名字创建Action对象
         * @param actionName:具体的Action类全名
         * @return :Action类型对象
         */
         public Action getAction(String actionClass) {
              Action actionInstance = null;
              try {
              Class c=Class.forName(actionClass);
                   actionInstance = (Action) c.newInstance();
              } catch (Exception e) {
                   e.printStackTrace();
              }
              return actionInstance;
         }
         //不需要创建对象
         private ActionFactory() {    }
         private static ActionFactory ac=null;
    }
    (3).Action接口类定义:
    这个接口定义非常简单,系统中所有的命令对象都必须实现这个接口,以便在控制器处理时,通过工厂类返回其对象。
    package cn.netjava.action;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    /**
    *系统中的命令处理器接口定义
    */
    public interface Action {
    /**
    * 所有的具体Action实现这个接口
    * @param request:请求对象
    * @param response:应答对象
    * @return :结果页面
    */
         public String execute(HttpServletRequest request, HttpServletResponse response);
       
    }




    以登陆这个具体动作为例它的实现:
    //登陆Action实现
    public class LoginAction implements Action {

         public String execute(HttpServletRequest request, HttpServletResponse response){
        String userName=request.getParameter("userName");
        String pwd=request.getParameter("pwd");
        //到数据库查找用户
        UserInfo user=MemoDBAccess.hasUser(userName, pwd);
        //有这个用户
        if(null!=user){
        //将用户对象放入session
        request.getSession().setAttribute("S_USER_OBJ",user);
        return "/mainPage.jsp";
        }
        request.setAttribute("R_ERROR_MSG"," 帐号或密码不正确!");
        return "/login.html";
       
         }
    }

    (4).web.xml中配置请求发送给控制器Servlet
    最后,我们只需要在wex.xml中对MVC结构的配置:
    视图面中的请求都是以<运作名字>.cn结尾,当这个请求到达web服务器后,会被服务器转向给控制器处理,控制器再根据解析出的动作名,调用对应的Action对象,处理结果,并输出结果页面,所以web.xml中必须有如下配置:
    <description>控制器servlet</description>
        <display-name>控制器servlet</display-name>
        <servlet-name>ControlActionServlet</servlet-name>
    <servlet-class>cn.netjava.control.ControlActionServlet</servlet-class>
    <!-- 将具体Action名字和全类名配置到Servlet参数中 -->
         <init-param>
          <param-name>ActionName</param-name>
        <param-value>cn.netjava.action.TheActionImpClassName</param-value>
         </init-param>
      </servlet>
    <servlet-mapping>
          <servlet-name>ControlActionServlet</servlet-name>
          <url-pattern>*.cn</url-pattern>
      </servlet-mapping>

    (5).系统视view层e实现:

    然后以一个具体的登录过程说下Action类的实现:
    表示层,即页面,接受用户输入数据,用户提交后,即发送给后台,经过控制器转发给具体的Action处理,以下表为各个页面的效果和代码:
    Login.jsp登陆页面


  •  

    代码:
    <%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
    <html><head><title>SampleBBS--你问我答---蓝杰信息@www.NetJava.cn</title>
      </head>  <body>
    <form name="testForm" method="get" action="LoginAction.netjava">
      <br>用户名: <input type="text" name="userName"/>
      <br>密&nbsp;&nbsp;&nbsp;  码: <input type="password" name="pwd"/>
      <%
      String errorMsg=(String)request.getAttribute("R_ERROR_MSG");
      if(null!=errorMsg){
       out.print("<br>"+errorMsg);
      }
       %>
    <input type="Submit" name="submit" value="登陆"/>
    </form>  <a href="userReg.html">注册新用户</a>
      </body></html>

三 . MVC的优点和缺点: 
      1 、 优点

  • 首先,最重要的一点是多个视图能共享一个模型,正如我所提及的,现在需要用越来越多的方式来访问你的应用程序。对此,其中一个解决之道是使用MVC,无论你的用户想要Flash界面或是 WAP 界面;用一个模型就能处理它们。由于你已经将数据和业务规则从表示层分开,所以你可以最大化的重用你的代码了。

    由于模型返回的数据没有进行格式化,所以同样的构件能被不同界面使用。例如,很多数据可能用HTML来表示,但是它们也有可能要用Macromedia Flash和WAP来表示。模型也有状态管理和数据持久性处理的功能,例如,基于会话的购物车和电子商务过程也能被Flash网站或者无线联网的应用程序所重用。

    因为模型是自包含的,并且与控制器和视图相分离,所以很容易改变你的应用程序的数据层和业务规则。如果你想把你的数据库从MySQL移植到Oracle,或者改变你的基于RDBMS数据源到LDAP,只需改变你的模型即可。一旦你正确的实现了模型,不管你的数据来自数据库或是LDAP服务器,视图将会正确的显示它们。由于运用MVC的应用程序的三个部件是相互对立,改变其中一个不会影响其它两个,所以依据这种设计思想你能构造良好的松偶合的构件。

    对我来说,控制器的也提供了一个好处,就是可以使用控制器来联接不同的模型和视图去完成用户的需求,这样控制器可以为构造应用程序提供强有力的手段。给定一些可重用的模型和视图,控制器可以根据用户的需求选择模型进行处理,然后选择视图将处理结果显示给用户。
  •      2 、缺点:
    MVC的缺点是由于它没有明确的定义,所以完全理解MVC并不是很容易。使用MVC需要精心的计划,由于它的内部原理比较复杂,所以需要花费一些时间去思考。

    你将不得不花费相当可观的时间去考虑如何将MVC运用到你的应用程序,同时由于模型和视图要严格的分离,这样也给调试应用程序到来了一定的困难。每个构件在使用之前都需要经过彻底的测试。一旦你的构件经过了测试,你就可以毫无顾忌的重用它们了。

    根据我个人经验,由于我们将一个应用程序分成了三个部件,所以使用MVC同时也意味着你将要管理比以前更多的文件,这一点是显而易见的。这样好像我们的工作量增加了,但是请记住这比起它所能带给我们的好处是不值一提。

    MVC并不适合小型甚至中等规模的应用程序,花费大量时间将MVC应用到规模并不是很大的应用程序通常会得不偿失。

四. MVC的拓展: 

 

           MVC框架的一种实现模型
          模型二(Servlet-centric):
           JSP+Servlet+JavaBean,以控制为核心,JSP只负责显示和收集数据,Sevlet,连接视图和模型,将视图层数据,发送给模型层,JavaBean,分为业务类和数据实体,业务类处理业务数据,数据实体,承载数据,基本上大多数的项目都是使用这种MVC的实现模式。

StrutsMVC框架(Web application frameworks)

Struts是使用MVC的实现模式二来实现的,也就是以控制器为核心。

Struts提供了一些组件使用MVC开发应用程序:
Model:Struts没有提供model类。这个商业逻辑必须由Web应用程序的开发者以JavaBean或EJB的形式提供

View:Struts提供了action form创建form bean, 用于在controller和view间传输数据。此外,Struts提供了自定义JSP标签库,辅助开发者用JSP创建交互式的以表单为基础的应用程序,应用程序资源文件保留了一些文本常量和错误消息,可转变为其它语言,可用于JSP中。

Controller:Struts提供了一个核心的控制器ActionServlet,通过这个核心的控制器来调用其他用户注册了的自定义的控制器Action,自定义Action需要符合Struts的自定义Action规范,还需要在struts-config.xml的特定配置文件中进行配置,接收JSP输入字段形成Action form,然后调用一个Action控制器。Action控制器中提供了model的逻辑接口。


     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值