MVC模式设计思想

1、MVC模式概念

    MVC模式的全名是Model View Controller,是模型(Model )-视图(View )-控制器(Controller)的缩写。首先要明确的一点是:MVC模式它不是类,也不是什么框架,它只是一种开发的设计思想。将业务逻辑、数据处理、界面显示分别抽取出来统一放到一个地方。从而使同一个程序可以使用不同的表现形式。

    MVC的思想就是把我们的程序分为三个核心的模块,这三个模块的详细介绍如下:

  • 模型(Model):负责封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。模型层有对数据直接访问的权力,例如对数据库的访问。它不关心它会如何被视图层显示或被控制器调用,它只接受数据并处理,然后返回一个结果。
  • 视图(View):负责应用程序对用户的显示,它从用户那里获取输入数据并通过控制层传给业务层处理,然后再通过控制层获取业务层返回的结果并显示给用户。
  • 控制器(Controller):负责控制应用程序的流程,它接收从视图层传过来的数据,然后选择Model层中的某个业务来处理,接收Model层返回的结果并选择视图层中的某个视图来显示结果。

    我们可以用下图来表示MVC模式中三者之间的关系:

image

    MVC模式的开发没有统一的标准,其中最典型的MVC模式开发思想为:JavaBean+JSP+Servlet。

  • JavaBean作为模型,既可以作为数据模型来封装业务数据,又可以作为业务逻辑模型来包含应用的业务操作。其中,数据模型用来存储或传递业务数据,而业务逻辑模型接收到控制器传过来的模型更新请求后,执行特定的业务逻辑处理,然后返回相应的执行结果。
  • JSP作为视图,负责提供页面为用户展示数据,提供相应的表单(Form)来用于用户的请求,并在适当的时候(点击按钮)向控制器发出请求来请求模型进行更新。
  • Serlvet作为控制器,用来接收用户提交的请求,然后获取请求中的数据,将之转换为业务模型需要的数据模型,然后调用业务模型相应的业务方法进行更新,同时根据业务执行结果来选择要返回的视图。

    不过我们在实际的开发中会把它们拆分的更细,从而形成entity+dto+dao+service+controller+html结构,其中entity+dto+dao+service为模型层,controller为控制器层,html为视图层。下面简单介绍一下:

类型 名称 作用
entity 实体类 一般与数据库的表相对应,封装dao层取出来的数据为一个对象,也就是我们常说的pojo,一般只在dao层与service层之间传输。
dao 数据访问层 作用是与数据打交道,可以是数据库操作,也可以是文件读写操作,甚至是redis缓存操作,总之与数据操作有关的都放在这里。
dto 数据传输层 主要用于远程调用等需要大量传输对象的地方。假如一个表有25个数据,而显示的只要5个,所有没必要将所有的属性都传输过去。
service 业务逻辑层 业务逻辑层用于调用dao层,从而处理一下业务逻辑,如拼接SQL,处理事务等。
controller 控制器层 接收从视图层传过来的数据,然后选择service层中的某个业务来处理,接收service层返回的结果并选择视图层中的某个视图来显示结果。

2、MVC模式的优缺点

    MVC模式之所以能够被广泛的使用到系统中,肯定是有它的优势所在,否则的话也不会存活至今。

    MVC的优点:

  1. 降低耦合度:由于模型、视图和控制器各个层都是分离的,这样在某个层需要改变的时候只需要改变相应层中代码即可,而不用关心其它的层。
  2. 重用性高:我们可以在不同的视图来访问同一个服务器端的代码,例如在主界面我可以查询,而在后台也可以使用相同的查询功能,但返回的数据是一样的。
  3. 可维护性高:在修改模型的情况下不会影响到视图,反过来,修改视图,也不会影响到模型。

    MVC的缺点:

  1. 完全理解MVC较复杂:实际的项目拆分了很多层,刚开始学习时不知道各个层的作用。记得自己刚刚学习的时候理解了好久。
  2. 代码量增加:既然将项目拆分成很多模块,就必然会导致代码量的增加、相应地也会增加软件开发的成文,设计的难度也会增加。
  3. 系统结构复杂:如果系统小一点到没什么,如果是大型系统的话,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。

总之MVC模式开发的优点是大于缺点的。

3、MVC模式的实现

    MVC模式的实现:javabean+dao+servlet+jsp实现一个简单的登录功能。

    注意:在搞代码是自己遇到了一个问题就是,我明明导入了MySQL的包,但是它还是一直报错com.mysql.jdbc.Driver找不到,然后百度了好久,说是将MySQL的驱动包复制到Tomcat的lib目录下就可以的,起初我还不信,结果试了一下居然成功了,也不再是为什么。还是自己太菜了image

①、创建一个名为user的数据库,然后创建一个名为t_user的表,如下:

image

②、创建视图层

login.jsp代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
  <title>登录页面</title>
</head>

<body>
<h1 style="color: red;">欢迎您登录系统</h1><hr/>
<div>
  <form method="post" action="/login">
    <table>
      <tr>
        <td>Username:</td>
        <td><input type="text" name="username" value="${username}"/></td>
      </tr>

      <tr>
        <td>Password:</td>
        <td><input type="password" name="password" value="${password}"/></td>
      </tr>

      <tr>
        <td></td>
        <td>
          <input type="submit" value="登录"/>
          <input type="reset" value="重置"/>
            <span style="color: red">${error}</span>
        </td>
      </tr>
    </table>
  </form>
</div>
</body>
</html>

success.jsp代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
  <title>登录成功</title>
</head>

<body>
<div>
  <h2>欢迎登陆</h2>
  当前登陆的用户为:${currentUser.userName}
</div>
</body>
</html>

③、创建模型层

User实体代码:

package com.thr.entity;

/**
 * @author tanghaorong
 * @date 2020-05-13
 * @desc 模型层
 */
public class User {
    private Integer id;
    private String userName;
    private String password;

    //get、set、toSting方法省略
}

对象数据操作的UserDao层代码:

package com.thr.dao;

        import com.thr.entity.User;
        import java.sql.*;

/**
 * @author tanghaorong
 * @date 2020-05-13
 * @desc 模型层
 */
public class UserDao {

    public User login(String username,String password){
        //创建JDBC的一些对象
        Connection con = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        User resultUser = null;

        try {
            //加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://localhost:3306/user?characterEncoding=UTF-8";
            String name = "root";
            String pwd = "root";
            //创建连接
            con = DriverManager.getConnection(url, name, pwd);
            String sql = "select * from t_user where username = ? and password = ?";
            //预编译SQL
            ps = con.prepareStatement(sql);
            ps.setString(1,username);
            ps.setString(2,password);
            //执行SQL,并返回结果
            rs = ps.executeQuery();
            while (rs.next()){
                resultUser= new User();
                //将结果封装到User对象中
                resultUser.setId(rs.getInt(1));
                resultUser.setUserName(rs.getString(2));
                resultUser.setPassword(rs.getString(3));
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //关闭连接
            if(rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(ps!=null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(con!=null){
                try {
                    con.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        //返回User对象
        return resultUser;
    }
}

④、控制器层

UserServlet代码:

package com.thr.controller;

import com.thr.dao.UserDao;
import com.thr.entity.User;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @author tanghaorong
 * @date 2020-05-13
 * @desc 控制器层
 */
@WebServlet(name = "UserServlet",value = "/login")
public class UserServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //获取前端表单发来的数据
        String userName=request.getParameter("username");
        String password=request.getParameter("password");
        //调用Dao模型层,从数据库中去数据
        UserDao userDao = new UserDao();
        User currentUser=userDao.login(userName, password);
        if(currentUser==null){
            request.setAttribute("error", "用户名或密码错误");
            request.setAttribute("userName", userName);
            request.setAttribute("password", password);
            request.getRequestDispatcher("login.jsp").forward(request, response);
        }else{
            HttpSession session=request.getSession();
            session.setAttribute("currentUser", currentUser);
            response.sendRedirect("success.jsp");
        }
    }
}

⑤、运行结果

GIF 2020-5-14 16-46-16

原文地址:https://www.cnblogs.com/tanghaorong/p/12832737.html