🥳🥳Welcome Huihui's Code World ! !🥳🥳
接下来看看由辉辉所写的关于自定义MVC的相关操作吧
目录
🥳🥳Welcome Huihui's Code World ! !🥳🥳
一.什么是自定义MVC框架?
二.自定义MVC框架与MVC三层架构有什么联系与区别
1.联系:
2.区别:
三.为什么要使用自定义MVC框架
四.自定义MVC框架原理
五.自定义MVC框架原理的代码分析与实现
1.如果没有使用MVC自定义框架,那么我们会怎么编写代码呢?
1.1jsp
1.2servlet(模拟)
1.3问题:servlet太多➡类太多
2.解决类太多的问题➡将操作的方法作为参数,使用一个servlet完成
2.1jsp
2.2servlet(模拟)
2.3问题:增加不同的操作,需要进行多次重复的语句判断➡判断的代码冗余
3.解决判断的代码冗余的问题➡使用反射动态获取方法
3.1jsp
3.2servlet
3.3问题:反射的代码会多次出现在不同的处理业务操作的类中➡反射的代码冗余
4.为解决反射的代码冗余➡将反射的代码抽离出来
一.什么是自定义MVC框架?
自定义 MVC 框架是基于模型-视图-控制器(Model-View-Controller,MVC)设计模式的一种框架,它允许开发者根据自己的需求和偏好,自行构建和定制符合自己业务逻辑的 MVC 框架
MVC 框架是一种软件架构模式,它将应用程序分为三个核心部分:
- 1. 模型(Model):负责处理应用程序的数据逻辑,包括数据的存储、检索、更新等操作
- 2. 视图(View):负责展示数据给用户,通常是通过用户界面来呈现模型中的数据
- 3. 控制器(Controller):作为模型和视图之间的中间层,它接收用户的输入并根据输入更新模型和视图
自定义 MVC 框架允许开发者根据应用程序的需要自行定义和实现这三个核心部分。相较于使用现有的 MVC 框架,自定义 MVC 框架提供了更大的灵活性和可定制性,开发者可以根据自己的要求选择合适的技术栈、组件和工具,以及定义自己的命名规则、目录结构、路由配置等
通过自定义 MVC 框架,开发者可以更好地理解和掌控应用程序的结构和流程,提高代码重用性和可维护性
二.自定义MVC框架与MVC三层架构有什么联系与区别
自定义 MVC 框架和三层架构是两个不同的概念,但它们可以在某种程度上相互关联。下面是它们之间的联系和区别:
1.联系:
- 1.1分层结构:自定义 MVC 框架和三层架构都关注将应用程序分为不同的层次结构,以实现代码的组织和模块化。它们都提倡将应用程序的不同功能划分为不同的层,以实现分工协作、代码重用和易维护性。
- 1.2解耦和扩展性:自定义 MVC 框架和三层架构都倡导通过解耦和模块化来实现系统的扩展性。通过将应用程序的不同模块分离,可以更容易地修改、替换或添加新的功能,而不会对整个系统产生较大的影响。
2.区别:
- 2.1.关注点不同:自定义 MVC 框架主要关注用户界面和用户交互层面的开发,通过模型-视图-控制器的分离将应用程序的视图与业务逻辑分离开来,以实现代码的可维护性和可测试性。而三层架构主要关注数据处理和业务逻辑层面的开发,通过数据访问层、业务逻辑层和表示层的分离,实现数据的持久化和业务逻辑的处理。
- 2.2 框架 vs 架构:自定义 MVC 框架更加具体和具体化,它是一个针对特定用户界面和交互的框架。而三层架构是一种通用的软件架构模式,它不关注具体的技术实现,更加关注应用程序的整体结构和组织。
- 2.3.范围不同:自定义 MVC 框架通常只关注应用程序的前端开发,涉及用户界面和用户交互的实现。而三层架构则是一种更为全面的架构模式,它涵盖了整个应用程序的开发,并关注数据处理、业务逻辑和表示层的组织和分离。
需要注意的是,自定义 MVC 框架和三层架构可以同时应用于一个应用程序中,以实现更好的代码组织和模块化。自定义 MVC 框架可以用于前端开发,将用户界面和交互分离开来;而三层架构可以用于后端开发,将数据处理和业务逻辑分离开来。这样可以实现更清晰的代码结构和更好的代码组织
三.为什么要使用自定义MVC框架
- 1. 灵活性和定制性:自定义 MVC 框架允许根据应用程序的需求来定制框架的各个部分。您可以选择适合项目的技术栈、组件和工具,定义自己的命名规则、目录结构、路由配置等。这样可以更好地适应特定的项目需求,减少不必要的冗余和复杂性
- 2. 理解和掌控:通过自定义 MVC 框架,能更好地理解和掌控应用程序的结构和流程。您可以深入了解框架的工作原理,以及每个组件在请求处理过程中的作用。这有助于更好地调试和优化代码,同时也提高了对整个应用程序的把控能力
- 3. 可定制的路由和请求处理:自定义 MVC 框架允许您灵活控制路由和请求处理的方式。可以自定义路由规则,将不同的请求映射到相应的控制器和操作方法上,并根据需要执行预处理、数据验证、权限验证等操作。这样可以更好地控制请求的处理流程,并更好地满足特定的业务需求
- 4. 增强的代码重用性和可维护性:通过自定义 MVC 框架,可以定义通用的模块和组件,提高代码的重用性。这样可以减少重复劳动和代码冗余,并提高开发效率。同时,自定义 MVC 框架也可以通过合理的分层和组织结构来提高代码的可维护性,使代码更易于理解、测试和修改
- 5. 适应新技术和需求:自定义 MVC 框架使您更加灵活地适应新技术和需求。当新的技术出现时,可以根据需要轻松集成和应用到自定义框架中。同样,当项目需求发生变化时,也可以相应地调整框架的实现,而无需受限于现有框架的限制
四.自定义MVC框架原理
先看看上面的原理图,我们可以看到,当浏览器发出一个请求之后,是直接去往了一个‘ActionServlet’,这个类是负责找到对应的子控制器去处理请求,也就是下面的Action,在这里面会对发出的请求进行具体的处理(里面有一个反射机制去统一的处理业务操作),往后需要做业务操作的类只需要继承Action便可,然后在自己的类中进行操作(增删改查)【如果是Book,那么便对Book进行相关操作,只需要在相关的BookAction中继承Action,如果是Order,User也是一样的流程】
多说无益,直接展示代码会比较直观,那么话不多说,我们直接上代码!!
五.自定义MVC框架原理的代码分析与实现
1.如果没有使用MVC自定义框架,那么我们会怎么编写代码呢?
1.1jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>自定义MVC</title> </head> <body> <!-- 版本1 我们平常这样子写的话,那么就是每一个操作都要对应一个servlet,那就会引发一个问题 ➡类太多 --> <a href="add.do">增加</a> <a href="del.do">删除</a> <a href="upd.do">修改</a> <a href="select.do">查询</a> <hr> </body> </html>
1.2servlet(模拟)
因为是模拟,就不做代码展示了,但是我们也可以看到,这样会有许多的servlet
1.3问题:servlet太多➡类太多
-------------------------------------------------------------------------------------------------------------------------
2.解决类太多的问题➡将操作的方法作为参数,使用一个servlet完成
2.1jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>自定义MVC</title> </head> <body> <!-- 版本2 将所有的操作放到同一个servlet中去处理,这样解决了上一个版本的问题,但随之而来的又会引发新的问题 ➡当我需要再新加一个操作时,我还需要在servlet写一份判断语句,使用起来还是不方便--> <a href="book.do?methodname=add">增加</a> <a href="book.do?methodname=del">删除</a> <a href="book.do?methodname=upd">修改</a> <a href="book.do?methodname=select">查询</a> <a href="book.do?methodname=selectSinger">查询单个</a> <hr> </body> </html>
2.2servlet(模拟)
package com.wh.servlet; import java.io.IOException; import java.lang.reflect.Method; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/book.do") public class BookServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String methodname = request.getParameter("methodname"); if("add".equals(methodname)) { add(request,response); }else if ("del".equals(methodname)) { del(request,response); }else if ("upd".equals(methodname)) { upd(request,response); }else if ("select".equals(methodname)) { select(request,response); }else if ("selectSinger".equals(methodname)) { selectSingel(request,response); } } private void selectSingel(HttpServletRequest request, HttpServletResponse response) { System.out.println("BookServlet查询单个"); } private void select(HttpServletRequest request, HttpServletResponse response) { System.out.println("BookServlet查询"); } private void upd(HttpServletRequest request, HttpServletResponse response) { System.out.println("BookServlet修改"); } private void del(HttpServletRequest request, HttpServletResponse response) { System.out.println("BookServlet删除"); } private void add(HttpServletRequest request, HttpServletResponse response) { System.out.println("BookServlet增加"); } }
2.3问题:增加不同的操作,需要进行多次重复的语句判断➡判断的代码冗余
-------------------------------------------------------------------------------------------------------------------------
3.解决判断的代码冗余的问题➡使用反射动态获取方法
3.1jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>自定义MVC</title> </head> <body> <!--版本3 为解决上一个版本的问题,因为它的判断语句都是一样的,只有传过来的方法参数不一样,我们可以使用反射去拿到指定类的指定方法,这样不管是什么操作,我都可以使用同样的代码块去完成 ,这在平常还是可以的, ➡但要是我们用大局观来看待,将其放到项目中,那我处理不同表的操作时,我需要在每一个表对应servlet中都写上反射的代码,这样也还是会造成代码冗余--> <a href="book.do?methodname=add">增加</a> <a href="book.do?methodname=del">删除</a> <a href="book.do?methodname=upd">修改</a> <a href="book.do?methodname=select">查询</a> <a href="book.do?methodname=selectSinger">查询单个</a> <hr> </body> </html>
3.2servlet
package com.wh.servlet; import java.io.IOException; import java.lang.reflect.Method; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/book.do") public class BookServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { String methodname = request.getParameter("methodname"); Method m=this.getClass().getDeclaredMethod(methodname, HttpServletRequest.class,HttpServletResponse.class); m.setAccessible(true); m.invoke(this, request,response); } catch (Exception e) { e.printStackTrace(); } } private void selectSingel(HttpServletRequest request, HttpServletResponse response) { System.out.println("BookServlet查询单个"); } private void select(HttpServletRequest request, HttpServletResponse response) { System.out.println("BookServlet查询"); } private void upd(HttpServletRequest request, HttpServletResponse response) { System.out.println("BookServlet修改"); } private void del(HttpServletRequest request, HttpServletResponse response) { System.out.println("BookServlet删除"); } private void add(HttpServletRequest request, HttpServletResponse response) { System.out.println("BookServlet增加"); } }
3.3问题:反射的代码会多次出现在不同的处理业务操作的类中➡反射的代码冗余
-------------------------------------------------------------------------------------------------------------------------
4.为解决反射的代码冗余➡将反射的代码抽离出来
4.1jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>自定义MVC</title> </head> <body> <!--版本4,为解决反射代码冗余的问题,那我们是不是可以想着把这些重复的代码抽离出来呢?让需要进行业务处理的实体都统一的去一个地方拿取反射的代码,然后在自己对应的servlet中做相应的操作 --> <a href="book.action?methodname=add">增加</a> <a href="book.action?methodname=del">删除</a> <a href="book.action?methodname=upd">修改</a> <a href="book.action?methodname=select">查询</a> <a href="book.action?methodname=selectSinger">查询单个</a> </body> </html>
4.2中央控制器
package com.wh.framwork; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletConfig; 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.wh.servlet.BookAction; /** * 中央控制器 * @author W * */ @WebServlet("*.action") public class DispatherAction extends HttpServlet { private Map<String, Action> actions = new HashMap<String, Action>(); @Override public void init(ServletConfig config) throws ServletException { actions.put("/book", new BookAction()); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String url = req.getRequestURI(); url = url.substring(url.lastIndexOf("/"), url.lastIndexOf(".")); Action action = actions.get(url); action.execute(req, resp); } }
4.3子控制器
package com.wh.framwork; import java.lang.reflect.Method; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Action { public void execute(HttpServletRequest request, HttpServletResponse response) { //反射的代码 String methodname = request.getParameter("methodname"); try { Method m=this.getClass().getDeclaredMethod(methodname, HttpServletRequest.class,HttpServletResponse.class); m.setAccessible(true); m.invoke(this, request,response); } catch (Exception e) { e.printStackTrace(); } } }
4.4实现类
package com.wh.servlet; import java.io.IOException; import java.lang.reflect.Method; 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.wh.framwork.Action; /** * book类需要进行的业务操作 * @author W * */ public class BookAction extends Action { public void selectSingel(HttpServletRequest request, HttpServletResponse response) { System.out.println("BookServlet查询单个"); } public void select(HttpServletRequest request, HttpServletResponse response) { System.out.println("BookServlet查询"); } public void upd(HttpServletRequest request, HttpServletResponse response) { System.out.println("BookServlet修改"); } public void del(HttpServletRequest request, HttpServletResponse response) { System.out.println("BookServlet删除"); } public void add(HttpServletRequest request, HttpServletResponse response) { System.out.println("BookServlet增加"); } }
上述的运行结果都是输出方法的对应语句,因为都是一样的,在这里就没有做展示了
好啦,今天的分享就到这了,希望能够帮到你呢!😊😊