自定义MVC

news/2024/5/9 23:46:25/文章来源:https://blog.csdn.net/weixin_74383330/article/details/131460055

目录

一、MVC概念描述

1、什么是MVC?

2、什么是自定义MVC?

3、自定义MVC有什么用(主要用途)?

二、MVC三层架构

第一种版本

JSP页面

servlet

 结果

第二种版本

 JSP代码

servlet

结果

第三种版本

jsp页面

servlet

结果

三、自定义MVC框架的雏形

工作原理图

类的创建

实践:第四种版本

jsp代码

debug测试

结果

帮助


一、MVC概念描述

1、什么是MVC?

MVC是一种设计模式,用于开发软件应用程序。它将应用程序分为三个核心部分:模型(Model)、视图(View)和控制器(Controller)

  • 模型(Model)是应用程序的数据和业务逻辑层。它负责处理数据的读取、存储、更新和删除,以及定义业务规则和逻辑。
  • 视图(View)是用户界面的呈现层,负责展示数据给用户,并接收用户的输入。视图通常是用户可以看到和与之交互的界面元素,如图形界面、网页或移动应用程序的界面。
  • 控制器(Controller)是模型和视图之间的中介,负责处理用户的输入、控制数据的流动以及调度视图的更新。它接收来自用户界面的输入,然后通过更新模型或通知视图来响应这些输入。

MVC的目标是将应用程序的逻辑和用户界面分离,使得代码更容易维护修改测试。通过将应用程序的不同部分分隔开来,可以提高代码的可读性可扩展性可重用性

2、什么是自定义MVC?

自定义MVC是指根据特定项目的需求和规模,自行设计和实现的MVC架构。传统的MVC架构提供了一种通用的模式来组织应用程序,但在特殊情况下,可能需要根据项目的特定需求,做一些定制化的调整或扩展。

自定义MVC使开发团队能够根据项目的需要,灵活地定义模型视图控制器的职责以及它们之间的通信机制。可以根据具体业务需求来调整模型控制器的逻辑设计符合项目需求的视图层。这样能够更好地满足项目的特殊要求,提高开发效率和代码质量。

在自定义MVC中,开发人员可以自由选择设计使用技术和工具,并根据项目的需要来决定是否引入其他架构模式或设计模式。这样可以根据具体的场景,综合考虑各种因素,选择最适合项目需求的架构方案。

自定义MVC是根据项目需求和规模设计的定制化MVC架构,能够更好地满足特定项目的要求,并提高开发效率和代码质量

3、自定义MVC有什么用(主要用途)?

  1. 灵活性和定制化:自定义MVC允许开发团队根据项目的具体需求来调整和扩展MVC的各个组成部分,以更好地满足特定项目的要求。可以根据具体场景自由选择和设计使用的技术和工具,以及决定是否引入其他架构模式或设计模式。
  2. 代码组织和可维护性:通过自定义MVC,开发人员可以将应用程序的不同层(模型、视图和控制器)进行清晰分离,并明确各自的职责。这样有助于更好地组织和管理项目代码,提高代码的可维护性和可读性。
  3. 可测试性:自定义MVC架构通常支持对不同部分进行单元测试或集成测试,从而提高代码的质量和可靠性。通过将业务逻辑从视图和控制器中剥离出来,可以更轻松地进行单元测试,并模拟不同场景来验证应用程序的功能。
  4. 适应性和扩展性:自定义MVC可以根据项目的增长和变化进行扩展和调整。如果对特定功能或模块需要进行更改或增加,可以根据需要修改模型、视图和控制器,而不会对整个应用程序产生过大的影响。这种灵活性和可扩展性有助于保持应用程序的可持续发展。
  5. 提高开发效率:通过自定义MVC,开发人员可以更好地组织和管理项目代码,优化开发流程,提高开发效率。不同开发人员可以更容易地理解和协同工作,将每个层的职责清晰分离,提高团队的协作效率。

自定义MVC提供了灵活性可定制化代码组织可维护性可测试性适应性扩展性以及提高开发效率等多个方面的优势,使开发团队能够更好地满足项目的需求并提高开发质量。

二、MVC三层架构

第一种版本

第一种方式是有弊端的:

        比如:你的每一个操作都需要编一个servlet类来处理

JSP页面

<%@ 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>index</title>
</head>
<body><h1>第一种</h1><a href="BookAddServlet">增加</a><a href="BookDelServlet">删除</a><a href="BookUpdateServlet">修改</a><a href="BookListServlet">查询</a><h1>第二种</h1><a href="">增加</a><a href="">删除</a><a href="">修改</a><a href="">查询</a><h1>第三种</h1><a href="">增加</a><a href="">删除</a><a href="">修改</a><a href="">查询</a></body>
</html>

servlet

我们可以利用重定向跳转到首页,这样可以更好的给我们一个体验
      

 response.sendRedirect("index.jsp");
package com.tgq.web;import java.io.IOException;
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 tgq**/
@WebServlet("/BookAddServlet")
public class BookAddServlet 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 {System.out.println("BookAddServlet");//利用重定向跳转到首页response.sendRedirect("index.jsp");}}

以此我们编写四个一样的servlet

 结果

我们依次点击增加===》删除===》修改===》查询

打印结果

第二种版本

弊端:虽然每一个对应每一个操作,只要写一个servlet来处理,但是每增加一个操作,都需要改变原有的代码块

 JSP代码

<%@ 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>index</title>
</head>
<body><h1>第一种</h1><a href="BookAddServlet">增加</a><a href="BookDelServlet">删除</a><a href="BookUpdateServlet">修改</a><a href="BookListServlet">查询</a><h1>第二种</h1><a href="BookServlet?methodName=add">增加</a><a href="BookServlet?methodName=del">删除</a><a href="BookServlet?methodName=update">修改</a><a href="BookServlet?methodName=list">查询</a><h1>第三种</h1><a href="">增加</a><a href="">删除</a><a href="">修改</a><a href="">查询</a></body>
</html>

servlet

package com.tgq.web;import java.io.IOException;
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 tgq**/
@WebServlet("/BookServlet")
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 (methodName.equals("add")) {add(request, response);} else if (methodName.equals("del")) {del(request, response);} else if (methodName.equals("update")) {update(request, response);} else if (methodName.equals("list")) {list(request, response);}response.sendRedirect("index.jsp");}private void list(HttpServletRequest request, HttpServletResponse response) {System.out.println("list");}private void update(HttpServletRequest request, HttpServletResponse response) {System.out.println("update");}private void del(HttpServletRequest request, HttpServletResponse response) {System.out.println("del");}private void add(HttpServletRequest request, HttpServletResponse response) {System.out.println("add");}}

结果

我们依次点击增加===》删除===》修改===》查询

输出结果:

第三种版本

弊端:

虽然解决了if条件分支代码冗余的问题,但是放在项目范围内,反射的代码时重复的

根据以上两种,我们进行一个优化修改

jsp页面

<%@ 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>index</title>
</head>
<body><h1>第一种</h1><a href="BookAddServlet">增加</a><a href="BookDelServlet">删除</a><a href="BookUpdateServlet">修改</a><a href="BookListServlet">查询</a><h1>第二种</h1><a href="BookServlet?methodName=add">增加</a><a href="BookServlet?methodName=del">删除</a><a href="BookServlet?methodName=update">修改</a><a href="BookServlet?methodName=list">查询</a><h1>第三种</h1><a href="BookServlet?methodName=add">增加</a><a href="BookServlet?methodName=del">删除</a><a href="BookServlet?methodName=update">修改</a><a href="BookServlet?methodName=list">查询</a></body>
</html>

servlet

package com.tgq.web;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;/*** * @author tgq**/
@WebServlet("/BookServlet")
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");try {// 利用反射调用方法Method method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);// 打开访问权限method.setAccessible(true);// 操作以下的代码不发生任何变化method.invoke(this, request, response);} catch (Exception e) {e.printStackTrace();}response.sendRedirect("index.jsp");}private void list(HttpServletRequest request, HttpServletResponse response) {System.out.println("list");}private void update(HttpServletRequest request, HttpServletResponse response) {System.out.println("update");}private void del(HttpServletRequest request, HttpServletResponse response) {System.out.println("del");}private void add(HttpServletRequest request, HttpServletResponse response) {System.out.println("add");}}

结果

我们依次点击增加===》删除===》修改===》查询

 输出结果:

三、自定义MVC框架的雏形

工作原理图

类的创建

我们需要新建一个包framework,在这个包下面我们新建两个类ClassDispatherServlet、Action)。

在我们原本的包下面新建一个类ClassBookAction

DispatherServlet:对应图中ActionServlet:中央处理器。

(需要继承HttpServlet:需要拦截所有的.action请求)

Action:子控制器,真正做事处理浏览器发送的请求类。

BookAction:需要继承Action

我们需要拿到我们请求的servlet的url,我们再把他截取下来。
需要一个容器来保存

public Map<String, Action> actionMaps = new HashMap<String, Action>();

利用init()方法初始化加载,添加进map集合保存

package com.tgq.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.tgq.web.BookAction;/*** 对应图中ActionServlet:中央处理器* * @author tgq**/
@WebServlet("/*.action")
public class DispatherServlet extends HttpServlet {public Map<String, Action> actionMaps = new HashMap<String, Action>();@Overridepublic void init() throws ServletException {actionMaps.put("/BookServlet", 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 {// 拿到url路径String uri = request.getRequestURI();// 拿到路径进行一个截取,拿到最后一个“/”到最后一个“.”之间的字符串uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));Action action = actionMaps.get(uri);}}

我们的反射代码需要写在Action

package com.tgq.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 tgq**/
public class Action {public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String methodName = request.getParameter("methodName");try {// 利用反射调用方法Method method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);// 打开访问权限method.setAccessible(true);// 操作以下的代码不发生任何变化method.invoke(this, request, response);} catch (Exception e) {e.printStackTrace();}}
}

我们把需要调用的方法写在BookAction

package com.tgq.web;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.tgq.framework.Action;public class BookAction extends Action {public void add(HttpServletRequest request, HttpServletResponse response) {System.out.println("add");}public void list(HttpServletRequest request, HttpServletResponse response) {System.out.println("list");}public void update(HttpServletRequest request, HttpServletResponse response) {System.out.println("update");}public void del(HttpServletRequest request, HttpServletResponse response) {System.out.println("del");}
}

最后我们在到我们的DispatherServlet,调用方法action.execute(request, response);
这就是我们的第四个版本:解决代码重复的问题

实践:第四种版本

jsp代码
 

<%@ 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>index</title>
</head>
<body><h1>第一种</h1><a href="BookAddServlet">增加</a><a href="BookDelServlet">删除</a><a href="BookUpdateServlet">修改</a><a href="BookListServlet">查询</a><h1>第二种</h1><a href="BookServlet.action?methodName=add">增加</a><a href="BookServlet.action?methodName=del">删除</a><a href="BookServlet.action?methodName=update">修改</a><a href="BookServlet.action?methodName=list">查询</a><h1>第三种</h1><a href="BookServlet.action?methodName=add">增加</a><a href="BookServlet.action?methodName=del">删除</a><a href="BookServlet.action?methodName=update">修改</a><a href="BookServlet.action?methodName=list">查询</a><h1>第四种</h1><a href="BookServlet.action?methodName=add">增加</a><a href="BookServlet.action?methodName=del">删除</a><a href="BookServlet.action?methodName=update">修改</a><a href="BookServlet.action?methodName=list">查询</a></body>
</html>

debug测试

我们在

 进行一个断点测试

我们依次点击增加===》删除===》修改===》查询

我们可以看到的断点的地方已经出现我们想要的结果了,走完之后就会调用

action.execute(request, response);

 

 

我们到action里面的这里打个断点,可以看到我们想要的结果了。最后跳进我们BookAction里面的方法

 

结果

 

帮助
 

如果想想我一样可以像这样建包、类等

 

希望对你们有用!谢谢!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_323792.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu18.04 系统设置修改物理内存-迅为RK3568开发板

打开虚拟机&#xff0c;如下图。单击红色框中的“虚拟机”。如下图所示&#xff1a; 然后点击“设置”弹出虚拟机的设置界面&#xff0c;如下图所示&#xff1a; 更多教程B站搜&#xff1a;迅为3568开发板

云原生运维实战 | 快速解决高可用K8s集群证书到期问题

欢迎关注「全栈工程师修炼指南」公众号 设为「星标⭐」每天带你 基础入门 到 进阶实践 再到 放弃学习&#xff01; 专注 企业运维实践、网络安全、系统运维、应用开发、物联网实战、全栈文章 等知识分享 “ 花开堪折直须折&#xff0c;莫待无花空折枝。 ” 作者主页&#xff1…

(小程序)uniapp调接口完整流程

(小程序)uniapp调接口完整流程 代码&#xff1a; <script lang"ts" setup>import { ref } from "vue"; const form ref({searchVal: "", });//搜索const searchClick () > {console.log(form.value.searchVal)let data {text: form…

Redis高并发分布式锁

文章目录 高并发场景秒杀抢购超卖Bug高并发场景秒杀抢购Demo测试结果 JVM级别锁使用nginx对本地服务进行负载均衡 Redis实现分布式锁Redis分布式锁实现DemoRedis分布式锁有关问题 分布式锁性能的提升减少锁的粒度使用异步处理 高并发场景秒杀抢购超卖Bug 在今天的数字化世界中&…

Python操作SQLite数据库

文章目录 这篇博客很简单&#xff0c;简单记录下SQLite基础使用。有些数据文件是.db为扩展名的&#xff0c;要用到SQLite进行读写和增删改查操作。SQLite数据库是一种轻量级的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;以单个文件的形式存储&#xff0c;整…

【数据挖掘】时间序列教程【二】

2.4 示例&#xff1a;颗粒物浓度 在本章中&#xff0c;我们将使用美国环境保护署的一些空气污染数据作为运行样本。该数据集由 2 年和 5 年空气动力学直径小于或等于 3.2017 \&#xff08;mu\&#xff09;g/m\&#xff08;^2018\&#xff09; 的颗粒物组成。 我们将特别关注来自…

优盘数据恢复怎么做?3个方法分享!

我的优盘里保存了很多有纪念意义的照片&#xff0c;但是刚刚将u盘插入电脑后&#xff0c;发现有些照片已经损坏了。我想将优盘里的数据恢复&#xff0c;有什么靠谱的方法吗&#xff1f;给我推荐一下吧&#xff01; 优盘是一种便携式存储设备&#xff0c;常用于存储和传输数据。…

Linux v4l2框架分析

1. 概述 V4L2(Video for Linux 2)&#xff1a;Linux内核中关于视频设备驱动的框架&#xff0c;对上向应用层提供统一的接口&#xff0c;对下支持各类复杂硬件的灵活扩展&#xff1b; V4L2框架&#xff0c;主要包括v4l2-core、meida framework、videobuf2等模块&#xff0c;这也…

攻防世界-Crypto-Normal_RSA

题目描述&#xff1a;下载附件后&#xff0c;附件中只有两个文件&#xff0c;一个是加密后的密钥&#xff0c;一个是公钥文件 背景知识&#xff1a;RSA加密算法 现在相当于给出了密文和公钥&#xff0c;需要我们去求解明文 1. 思路分析 既然要解密&#xff0c;那么必须要获取…

Facebook Insights分析工具解读,掌握关键数据指标

什么是Facebook Insights&#xff1f; Facebook Insights是Facebook平台上的一项内置分析工具&#xff0c;旨在帮助企业和品牌了解其在Facebook上的表现和受众互动情况。该工具提供了丰富的数据和指标&#xff0c;可以帮助用户洞察粉丝群体、了解发布内容的表现&#xff0c;并…

Hutool 30

Hutool是一个Java工具包&#xff0c;提供了丰富的工具类库和简化开发的工具方法。它的目标是提供一套丰富、实用、高效和易用的Java工具类&#xff0c;以提升开发者的开发效率和开发质量。以下是Hutool的一些主要特点和功能模块&#xff1a; 常用工具类&#xff1a;Hutool提供了…

百度智能车竞赛丝绸之路2——手柄控制

百度智能车竞赛丝绸之路1——智能车设计与编程实现控制 百度智能车竞赛丝绸之路2——手柄控制 一、机器人设计 二、实现原理 本教程使用Python的Serial库和Struct二进制数据解析库去实现Xbox手柄百度大脑学习开发板&#xff08;上位机&#xff09;和机器人控制器&#xff08;…

你的服务器还安全吗?用户数据是否面临泄露风险?

一系列严重的网络安全事件引起了广泛关注&#xff0c;多家知名公司的服务器遭到黑客挟持&#xff0c;用户的个人数据和敏感信息面临泄露的风险。这些事件揭示了网络安全的脆弱性和黑客攻击的威胁性&#xff0c;提醒着企业和个人加强对网络安全的重视。 一、入侵案例1.1 蔚来数据…

Pycharm中成功配置PyQt5(External Tools),设计好界面直接生成python代码

1、安装PyQt5和PyQt5-tools 在Pycharm中设置好Python环境&#xff0c;点击File-Settings-Project-Python Interpreter 设置好后退出&#xff0c;点击窗口下的Terminal&#xff0c;输入 # 直接安装输入pip install pyqt5&#xff0c;如果太慢可以用国内镜像源&#xff0c;若出…

PS扣签名

打开Photoshop CS6&#xff0c;依次点击“文件”-“打开”&#xff0c;把签名照导入进来。 在“选择”菜单下点击“色彩范围”。 此时鼠标形状变成了一支笔&#xff0c;点击签名上黑色的地方&#xff0c;适当调整颜色容差&#xff0c;点击“确定”完成选择。 按住CtrlJ组…

Postman设置断言

目录 前言&#xff1a; 一、断言的定义 二、Postman断言的语法 三、Postman中chai.js断言常用语法 前言&#xff1a; 在进行API测试时&#xff0c;断言是一项重要的功能。它能帮助我们验证接口的响应是否符合预期结果&#xff0c;从而确保API的正确性和可靠性。在Postman中…

【微服务】什么是微服务?-- 全面了解微服务架构

What is Microservices — Edureka 您有没有想过&#xff0c;什么是微服务以及扩展行业如何与它们集成&#xff0c;同时构建应用程序以满足客户的期望&#xff1f; 要了解什么是微服务&#xff0c;您必须了解如何将单体应用程序分解为独立打包和部署的小型微型应用程序。本文将…

Electron + ts + vue3 + vite 项目搭建

Electron 是一个基于 Chromium 和 Node.js 的桌面应用程序开发框架&#xff0c;而 Vue3 则是一种流行的前端框架。将两者结合使用可以快速地打造出跨平台的桌面应用程序。在这种组合中&#xff0c;Electron 提供了强大的桌面应用开发能力&#xff0c;而 Vue3 则提供了易用的 UI…

【2023年江西省研究生数学建模竞赛】题目一 蒸汽发生器倒U型管内液体流动 建模方案及参考文献

代码与结果如下&#xff1a;完整文档见文末 完整思路”请点击这里“到原文章获取 题目&#xff1a; PACTEL压水堆整体测试设备在2009年建造&#xff0c;用于带有垂直倒U型管蒸汽发生器的压水堆热液压相关的安全性研究,参见图1。 PACTEL压水堆设施包括一个反应堆压力容器模型…