一、MVC设计模式
1. 什么是MVC
MVC(Model-View-Controller)是一种软件设计模式,用于构建可维护和可扩展的应用程序。
MVC的结构:
- 模型(Model):模型表示应用程序的数据和业务逻辑。它负责处理数据操作、数据验证和业务规则。在自定义框架中,开发者需要定义模型来表示应用程序中的数据,并实现相应的操作和规则。
- 视图(View):视图负责展示模型的数据给用户,并处理用户界面的交互操作。视图通常是用户可见的部分,例如HTML页面或者移动应用的界面。在自定义框架中,开发者需要定义视图来展示模型的数据,并与用户进行交互。
- 控制器(Controller):控制器充当模型和视图之间的中间人,负责处理用户的请求并协调模型和视图之间的交互。它接收用户的输入,并将其转发给相应的模型进行处理,之后再将模型的结果传递给视图进行展示。在自定义框架中,开发者需要定义控制器来处理用户的请求,并根据请求调用相应的模型和视图。
2. 三层架构与MVC的区别
三层架构(Three-Tier Architecture)和MVC(Model-View-Controller)是两种不同的软件架构模式,它们的主要区别如下:
- 结构层次不同:三层架构将应用程序划分为三个主要层次,分别是表示层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access Layer)。而MVC将应用程序划分为三个组件,即模型(Model)、视图(View)和控制器(Controller)。
- 侧重点不同:三层架构的重点是将应用程序的不同功能和职责分离开来,以实现松耦合和重用性。每个层次负责不同的功能,比如表示层负责用户界面展示、业务逻辑层负责业务处理、数据访问层负责数据存储和检索。而MVC的重点是将应用程序的数据、视图和用户交互分离开来,并通过控制器协调它们之间的交互。
- 关注点不同:三层架构关注的是整体的系统架构和分层设计,注重将应用程序拆分为更小的组件并定义其功能和职责。MVC关注的是应用程序的交互和用户界面部分,注重实现数据与视图的分离以及交互逻辑的处理。
- 可重用性不同:三层架构的目标是实现组件的高内聚和低耦合,以便于组件的重用和替换。MVC的目标是实现模块化和可复用的代码,以便于视图和控制器的复用和替换。
总的来说,三层架构是一种更加宏观的架构模式,注重整体的系统设计和分层,而MVC是一种更具体的架构模式,注重应用程序的交互和用户界面设计。它们可以相互结合使用,三层架构可以作为整体架构的基础,而MVC可以作为其中的一部分组件,负责实现视图和控制器的功能。
二、自定义MVC框架
自定义MVC(Model-View-Controller)框架是一种能够帮助开发者构建和组织应用程序的软件框架,它基于MVC设计模式。
1. 为什么要学习自定义MVC框架
自定义MVC框架的重要性主要体现在以下几个方面:
- 结构清晰:MVC框架将应用程序的不同部分进行了划分,使得代码的结构更加清晰和可读性更高。通过明确定义模型、视图和控制器的职责,可以使开发人员更容易理解和维护应用程序的代码。
- 可维护性:由于MVC框架使代码结构变得清晰,因此应用程序变得更容易维护。当需要进行修改或者添加新功能时,开发人员可以更加准确地找到和理解相关代码的位置,从而提高代码的可维护性。
- 可扩展性:MVC框架将应用程序的不同部分解耦,使得各个部分可以独立进行开发和测试。这意味着当需要添加新功能或者进行需求变更时,只需要修改相应的模型、视图或控制器,而不会对其他部分造成影响,从而提高了代码的可扩展性。
- 代码复用:通过合理使用MVC框架,可以将一些通用的代码逻辑封装在模型、视图或控制器中,从而实现代码的复用。例如,多个视图可以共享同一个模型来展示不同的数据,或者多个控制器可以共享同一个模型来处理相同的请求。这样可以减少冗余代码的编写,提高开发效率。
学习自定义MVC框架也非常重要,因为它是一种常用的软件设计模式,广泛应用于Web开发和其他领域的应用程序开发中。通过学习MVC框架,你将掌握一种思维方式和组织代码的方法,提高自己的编程能力和项目开发能力。同时,理解MVC框架的原理和使用方式,可以让你更好地理解和使用各种现有的MVC框架,如Spring MVC、Ruby on Rails等,从而扩展你的技术栈。
2. 自定义MVC的工作原理
一个自定义MVC框架的基本工作流程如下:
- 用户通过视图与应用程序交互,视图将用户的请求传递给控制器。
- 控制器接收用户请求,根据请求的类型和内容决定调用哪个模型处理请求,并根据处理结果决定需要更新哪个视图。
- 模型处理请求的过程中可能需要与数据库或其他数据源进行交互,获取所需数据并进行相应的处理。处理完成后,将结果返回给控制器。
- 控制器根据模型的处理结果,决定更新哪个视图以展示结果给用户。
- 视图接收到控制器的指令后,根据要展示的内容进行相应的处理和渲染,最终将结果呈现给用户。
3. 自定义MVC框架的优势
- 分离关注点:MVC框架能够帮助开发者清晰地分离应用程序的不同组件,提高代码的可读性、可维护性和可重用性。
- 灵活性:开发者可以根据具体需求自由扩展和定制各个组件,以适应不同的应用场景。
- 易于测试:由于MVC框架的模型、视图和控制器各自独立,开发者可以方便地对每个组件进行单独的单元测试和集成测试。
根据具体的编程语言和需求,开发者可以根据MVC模式自定义属于自己的MVC框架,并根据实际情况进行相应的优化和扩展。
三、自定义MVC实例流程
1. mvc三层架构的弊端
你是否还在用之前的mvc架构方法🤷♂️?还在写这么多的包来进行分类!😯
或者这样🤔?不得不承认你是有点聪明在身上的👍
总结弊端:每一个操作都要写一个servlet来处理,每张表都要写相应的增删改改查方法
🫵今天看了我这篇自定义MVC框架!头也不疼了,脚也不酸了👨💻、代码也少了🤏
准备好上车了吗👴!!!
2. 自定义MVC的工作流程
👨💻 首先我给大家讲一个生活中的案例,假如我是一个施工人员,只有施工证才能进行施工。那么我要进行施工,每次都要经过施工点的门禁,门禁则根据施工证进行存档,通过了才能到达施工点,听从安排进行具体任务施工。
那么这里的的施工人员就是一个个子控制器子类,必须要继承实现父类子控制器的执行方法,才有资格进行操作,而我们子控制器子类真正要实现功能,要每次都经过主控制器的控制过滤,才能到指定子类进行施工,分发任务的就是子控制器了。
2.1 子控制器(分发任务)
package com.ycxw.framework; import java.lang.reflect.Method; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 子控制器(action) 处理浏览器请求的类 * * @author 云村小威 * * 2023年6月29日 下午8:30:32 */ public class Action { public void execute(HttpServletRequest request, HttpServletResponse response) throws Exception { // 获取methodName值,这里指前端点击功能传来的方法名 String methodName = request.getParameter("methodName"); /** * this--->BookAction/BlogAction/PermissionAction...可能是很多对象 * 所以需要通过反射找到对象带request,response参数的methidName方法 */ Method m = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class); m.setAccessible(true); // 动态调用其方法 m.invoke(this, request, response); } }
2.2 子控制器子类(施工员):
package com.ycxw.servlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ycxw.framework.Action; /** * 施工类 * 继承子控制器 * @author 云村小威 * * 2023年6月29日 下午8:32:59 */ public class BookAction extends Action { public void query(HttpServletRequest req, HttpServletResponse resp) { System.out.println("查询的业务逻辑"); } public void edit(HttpServletRequest req, HttpServletResponse resp) { System.out.println("修改的业务逻辑"); } public void delete(HttpServletRequest req, HttpServletResponse resp) { System.out.println("删除的业务逻辑"); } public void add(HttpServletRequest req, HttpServletResponse resp) { System.out.println("新增的业务逻辑"); } }
施工证就是 : public class BookAction extends Action
, 如果我没有继承Action父类子控制器,我是没有这个方法的,那么就不能进行施工操作…
2.3 主控制器(门禁):
package com.ycxw.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.ycxw.servlet.BookAction; /** * 中央控制器(ActionServlet) * * @author 云村小威 * * 2023年6月29日 下午8:14:38 */ @WebServlet("*.action") public class DisPathServlet extends HttpServlet { private static final long serialVersionUID = 1L; //实例化集合作为储存 private Map<String, Action> actionMap = new HashMap<String, Action>(); @Override public void init() throws ServletException { /** * 初始化存值就是给每个施工员根据施工证进行存档: */ actionMap.put("book", new BookAction()); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // http://localhost:8080/MVC_project/book.action?methodName=delete... /** * 获取请求路径 */ String uri = request.getRequestURI(); // 截取book uri = uri.substring(uri.lastIndexOf("/") + 1, uri.lastIndexOf(".")); // 通过截取后的key(url)在map集合中找到指定的类进行处理 Action action = actionMap.get(uri); try { action.execute(request, response); } catch (Exception e) { e.printStackTrace(); } } }
2.4 请求测试
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <a href="${pageContext.request.contextPath }/book.action?methodName=add">增加</a> <a href="${pageContext.request.contextPath }/book.action?methodName=delete">删除</a> <a href="${pageContext.request.contextPath }/book.action?methodName=edit">修改</a> <a href="${pageContext.request.contextPath }/book.action?methodName=query">查询</a> <a href="${pageContext.request.contextPath }/book.action?methodName=load">回显</a> </body> </html>
当我点击删除连接 就会进到主控制器进行筛选处理
通过子控制器动态调用传来的方法名指定的方法
尾言:
学好编程先学会编程思想,分析流程才能提高效率,本篇只是简单的介绍及流程,自定义MVC框架主要是促进了代码的重用性、可维护性和可扩展性。将代码进行分离,明确定义它们的职责。因此可以更容易地进行单元测试和集成测试。此外,当某个组件需要变更时,也只需要修改该组件而不影响其他组件。
下篇我会讲到如何将自定义MVC框架运用到实际开发中,加油!