自定义MVC框架原理

简介: 自定义MVC框架原理

一、什么是MVC?

MVC代表模型-视图-控制器,是一种经典的软件设计模式,常用于构建桌面应用程序、Web应用程序和移动应用程序。它将一个应用程序分为三个主要部分:

       1.模型(Model):

       2.视图(View):

负责展示和呈现数据给用户,通常是用户界面的组件。它根据模型的数据来渲染界面,提供用户与应用程序交互的界面。

       3.控制器(Controller):

充当模型和视图之间的中介,处理用户的输入和响应。它接收用户的动作并更新模型和视图的状态,确保它们保持同步。

二、自定义mvc核心思想

       自定义MVC架构的核心思想是将应用程序的不同功能部分分离开来,以实现更好的代码组织、可维护性和可扩展性。虽然MVC的基本架构已经定义了模型、视图和控制器,但是具体实现和组织方式可以根据项目的需求进行自定义。

三、自定义MVC的核心原则

  1. 核心组件分离: 保持模型、视图和控制器的独立性,每个组件都应该专注于自己的领域。模型负责数据处理和业务逻辑,视图负责展示界面,而控制器负责处理用户输入和协调其他组件。
  2. 清晰的通信接口: 定义清晰的接口和协议,以确保模型、视图和控制器之间的通信和交互是统一和可预测的。这可以减少耦合性,使组件更容易替换和扩展。
  3. 事件驱动: 引入事件驱动的思想可以提高MVC架构的灵活性和响应性。组件之间可以通过事件来进行通信,而不是直接调用方法。这样可以减少依赖关系,使系统更能适应变化。
  4. 分层架构: 根据应用程序的规模和复杂性,可以将MVC架构进一步分层。例如,可以引入服务层或数据访问层来处理特定的功能和访问外部资源,从而实现更好的代码分离和职责划分。
  5. 可测试性和可扩展性: 考虑如何设计MVC架构以便于测试和扩展。确保模型、视图和控制器的可测试性,以便能够进行单元测试和集成测试。同时,提供灵活的扩展点和插件机制,使新功能的添加和变更更加容易。

四、 三层架构和MVC的区别

1.结构层次不同:

  • 三层架构:将应用程序划分为表示层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access Layer)。
  • MVC:将应用程序划分为模型(Model)、视图(View)和控制器(Controller)。模型和视图负责应用程序的数据和界面,控制器负责处理用户输入和协调模型和视图之间的交互。

2.重点关注不同:

  • 三层架构:着重于将应用程序按照功能职责进行分层,将关注点分离,并提供更好的可维护性和可扩展性。
  • MVC:着重于将应用程序按照数据、界面和交互逻辑进行分离,实现用户界面和数据逻辑的解耦,并提供更好的用户体验和可重用性。

3.强调的功能不同

  • 三层架构:着重于数据的管理和持久化,业务逻辑的封装和处理,以及用户界面的展示和交互。
  • MVC:着重于界面的设计和呈现,用户交互的处理和响应,以及数据模型的管理和更新。

4.可扩展性和复用性不同:

  • 三层架构:通过明确的层次划分和职责分离,提供更好的可扩展性和模块化设计,使不同层级的组件可以独立地进行调整和替换。
  • MVC:通过分离数据逻辑、界面和交互逻辑,提供更好的复用性和可维护性,使视图和控制器可以被重用于不同的模型和业务逻辑。

五、MVC工作原理

举个栗子:

      比如说一个老板他开饭店,刚开始为了节约成本,他一个人做事,从早上起床买菜、洗菜、切菜,切完之后有客人来了、还要招呼客人,客人还要点单点完单之后又要去炒菜,这一系列下来都是他一个人做的,客人吃完之后他还要洗碗,前期当他店小的时候用户量小的情况下他一个人是可以做的到的。

       但是当他后期生意越来越好,想扩展规模越来越大的时候,他一个人就做不了这些事情了。

      此时只能请人分配各个岗位,老板就做管理,管理员工。(各司其职)

六、MVC结构对应关系

1.模型-视图对应关系:

  • 模型(Model):负责封装应用程序的数据和业务逻辑。
  • 视图(View):负责展示模型中的数据给用户。

在这个对应关系中,模型代表应用程序的数据和操作方法,它存储和管理数据,并提供与数据相关的操作。视图是用户界面的表示部分,它负责展示模型中的数据给用户,通常是以可视化的形式呈现,如HTML页面、图表、列表等。

2.控制器-视图对应关系:

  • 控制器(Controller):负责接收用户的输入和请求,并根据请求的类型和参数选择合适的视图进行展示。
  • 视图(View):负责接收控制器传递的数据并将其呈现给用户。

这个对应关系中,控制器充当了视图和模型之间的协调者和中介者。它接收用户的输入或请求,并根据请求对模型进行操作。一旦模型处理完成后,控制器选择适当的视图进行展示,将模型中的数据传递给视图进行渲染。

3.控制器-模型对应关系:

  • 控制器(Controller):负责接收用户的输入和请求,并根据请求的类型和参数选择相应的模型进行处理。
  • 模型(Model):负责处理数据逻辑和状态管理。

这个对应关系中,控制器负责接收用户的输入,根据输入的请求调用适当的模型来处理数据逻辑和状态管理。控制器根据模型的处理结果来决定下一步的行动,可以进行数据更新、查询、保存等操作。

术语 对应关系
M 实体域模型(名词)entity,过程域模型(动词:因为是可变的)dao/biz
V jsp
C servlet/action

七.优缺点

优点:

      耦合性低

      重用性高

      生命周期成本低

      可维护性高

      部署快

缺点:

      1.增加系统结构和实现的复杂性

对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。

      2.一般高级的界面工具或构造器不支持模式

改造这些工具以适应MVC需要和建立分离的部件的代价是很高的,会造成MVC使用的困难。

细讲原理图:

1.ActionServlet:中央控制层

2.子控制器Action中央控制器就是老板用来做管理的,子控制器就是各个员工,具体做事的那个人就叫子控制器。

注意:子控制器必须获取资格证才能上岗做事,这个资格证相当于Action
它里面有一个execute方法(处理具体逻辑)

八、自定义mvc的简单实现

1.中央控制器

通过servlet来实现一个中央控制器,负责所有请求的接收。(后续中央控制器在再将请求转发给各个子控制器,此处可以先把请求接进来,转发功能后面再加)

package com.ctb.framework;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 中央控制器,负责接收所有的请求并分别给控制器具体处理
 * @author biao
 */
@WebServlet("*.action")
public class ActionDispatchServlet extends HttpServlet {
  @Override
  public void doGet(HttpServletRequest req, HttpServletResponse resp) {
    doPost(req, resp);
  }
  @Override
  public void doPost(HttpServletRequest req, HttpServletResponse resp) {
    System.out.println("dopost ..... ");
  }
}

2.Action类定义

Action类定义了每个子控制器需要遵循的行为,使得所有的子控制器都有一个同一的抽象类型,所以我们可以在中央控制器中使用Action类类型来引用所有的子控制器。这样就为用户扩展自定义的子控制器提供了条件。

package com.ctb.framework;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 子控制器
 * 处理浏览器发送的请求
 * @author biao
 *
 * 2023年6月29日:下午7:08:41
 */
public class Action {
  protected void excute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("................");
  }
}

3.继承子控制器

package com.ctb.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ctb.framework.Action;
/**
 * 
 * @author biao
 *
 * 2023年6月29日:下午6:41:01
 */
public class BookAction extends Action{  
  System.out.println("欢迎来到.....");
}

4.完善中央控制器

为了便于理解,我们可以分步骤的,循序渐进的完善中央控制器:

  • 编写简单的请求分发实现功能
  • 实现子控制器的功能
  • 完善请求参数处理功能
1.请求分发功能
package com.ctb.framework;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
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 com.ctb.servlet.BookAction;
/**
 * 请求分发功能
 * @author biao
 *
 * 2023年6月29日:下午6:45:13
 */
@WebServlet("*.action")
public class DispathServlet extends HttpServlet{
//用于保存path与action子控制器的映射
  public Map<String, Action> actionMap=new HashMap<String, Action>();
  @Override
  public void init() throws ServletException {
    actionMap.put("/book", new BookAction());
  }
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    this.doPost(req, resp);
  }
  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //获取uri地址
    String uri = req.getRequestURI();
    //截取
    uri=uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
    //将uri放到map集合中存储
    Action action = actionMap.get(uri);
    //获取父类方法
    action.excute(req, resp);
  }
}
2.action子控制器

在上面的示例中,在中央控制器中直接创建action子控制器

package com.ctb.framework;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 子控制器
 * 处理浏览器发送的请求
 * @author biao
 *
 * 2023年6月29日:下午7:08:41
 */
public class Action {
  protected void excute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //获取页面传输的参数
    String action = req.getParameter("action");
    try {
      //反射动态方法调用
      Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class,HttpServletResponse.class);
      method.setAccessible(true);
      method.invoke(this, req,resp);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
3.请求参数处理功能
package com.ctb.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ctb.framework.Action;
/**
 * 
 * @author biao
 *
 * 2023年6月29日:下午6:41:01
 */
public class BookAction extends Action{  
  public  void detail(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("欢迎来到查看详情💕💕💕");
  }
  public  void del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("欢迎来到删除💕💕💕");   
  }
  public  void upd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("欢迎来到修改💕💕💕");   
  }
  public  void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("欢迎来到新增💕💕💕");   
  }
  public  void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("欢迎来到主页面💕💕💕");    
  }
}

接下来,我们建一个jsp页面简单测试一下

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<%-- <p>多个servlet进行增删改查</p>
<a href="${pageContext.request.contextPath }/list.do">查询</a>
<a href="${pageContext.request.contextPath }/edit.do">修改</a>
<a href="${pageContext.request.contextPath }/addbook.do">增加</a>
<a href="${pageContext.request.contextPath }/del.do">删除</a>
<a href="${pageContext.request.contextPath }/detail.do">查看详情</a>
<hr>
<p>一个servlet判断参数跳转增删改查方法</p>
<a href="book.action?action=list">查询</a>
<a href="book.action?action=upd">修改</a>
<a href="book.action?action=add">增加</a>
<a href="book.action?action=del">删除</a>
<a href="book.action?action=detail">查看详情</a>
<hr>
<p>反射获取参数调用方法</p>
<a href="book.do?action=list">查询</a>
<a href="book.do?action=upd">修改</a>
<a href="book.do?action=add">增加</a>
<a href="book.do?action=del">删除</a>
<a href="book.do?action=detail">查看详情</a> --%>
<hr>
<p>初步mvc</p>
<a href="book.action?action=list">查询</a>
<a href="book.action?action=upd">修改</a>
<a href="book.action?action=add">增加</a>
<a href="book.action?action=del">删除</a>
<a href="book.action?action=detail">查看详情</a>
</body>
</html>

页面显示:

测试结果:

这篇文章就到这里结束啦(づ ̄ 3 ̄)づ,拜拜。


相关文章
|
2月前
|
前端开发 Java 数据库
springBoot:template engine&自定义一个mvc&后端给前端传数据&增删改查 (三)
本文介绍了如何自定义一个 MVC 框架,包括后端向前端传递数据、前后端代理配置、实现增删改查功能以及分页查询。详细展示了代码示例,从配置文件到控制器、服务层和数据访问层的实现,帮助开发者快速理解和应用。
|
2月前
|
XML 前端开发 Java
拼多多1面:聊聊Spring MVC的工作原理!
本文详细剖析了Spring MVC的工作原理,涵盖其架构、工作流程及核心组件。Spring MVC采用MVC设计模式,通过DispatcherServlet、HandlerMapping、Controller和ViewResolver等组件高效处理Web请求。文章还探讨了DispatcherServlet的初始化和请求处理流程,以及HandlerMapping和Controller的角色。通过理解这些核心概念,开发者能更好地构建可维护、可扩展的Web应用。适合面试准备和技术深挖
47 0
|
2月前
|
前端开发 Java
【案例+源码】详解MVC框架模式及其应用
【案例+源码】详解MVC框架模式及其应用
137 0
|
4月前
|
设计模式 存储 前端开发
MVC 框架的主要问题是什么?
【8月更文挑战第30天】
92 0
|
6月前
|
安全 前端开发 测试技术
安全开发-PHP应用&模版引用&Smarty渲染&MVC模型&数据联动&RCE安全&TP框架&路由访问&对象操作&内置过滤绕过&核心漏洞
安全开发-PHP应用&模版引用&Smarty渲染&MVC模型&数据联动&RCE安全&TP框架&路由访问&对象操作&内置过滤绕过&核心漏洞
|
7月前
|
前端开发 Java Spring
Java Web ——MVC基础框架讲解及代码演示(下)
Java Web ——MVC基础框架讲解及代码演示
69 1
|
7月前
|
前端开发 Java 应用服务中间件
Spring MVC框架概述
Spring MVC 是一个基于Java的轻量级Web框架,采用MVC设计模型实现请求驱动的松耦合应用开发。框架包括DispatcherServlet、HandlerMapping、Handler、HandlerAdapter、ViewResolver核心组件。DispatcherServlet协调这些组件处理HTTP请求和响应,Controller处理业务逻辑,Model封装数据,View负责渲染。通过注解@Controller、@RequestMapping等简化开发,支持RESTful请求。Spring MVC具有清晰的角色分配、Spring框架集成、多种视图技术支持以及异常处理等优点。
89 1
|
7月前
|
设计模式 前端开发 网络协议
Java Web ——MVC基础框架讲解及代码演示(上)
Java Web ——MVC基础框架讲解及代码演示
56 0
|
4月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
55 0
|
7月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
211 0