深入解析Java自定义MVC框架的原理与实现)

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: 深入解析Java自定义MVC框架的原理与实现)

引言:

MVC(Model-View-Controller)是一种常见的软件设计模式,用于分离应用程序的逻辑和用户界面。MVC模式将应用程序分解为三个组件:模型(Model)、视图(View)和控制器(Controller)。在Java开发中,我们可以根据自身需求实现自定义的MVC框架。本文将深入解析Java自定义MVC框架的原理与实现方法,帮助读者理解MVC的工作原理,并通过实例代码来演示。

一、MVC的基本原理

1.模型(Model)

模型是应用程序的核心组件,负责处理数据和业务逻辑。模型可以是一个Java类,它表示应用程序的数据,并提供与数据相关的操作方法。模型通常封装了对数据库或其他数据源的访问。

2.视图(View)

视图是模型的可视化表现,负责呈现数据给用户,并接收用户的输入。视图可以使用Java的GUI库(如Swing或JavaFX)来构建用户界面,并通过监听事件来与控制器进行交互。

3.控制器(Controller)

控制器是模型和视图之间的协调者,负责处理用户的输入和相应的操作。控制器接收来自视图的事件,并根据事件的类型,使用模型来执行相应的操作。控制器还可以更新视图,以反映模型的变化。

二、自定义MVC框架的实现步骤

下面是一个简单的步骤,用于实现一个基本的自定义MVC框架:

1.创建模型类

创建一个Java类,表示应用程序的数据和业务逻辑。在模型类中定义数据字段和相应的操作方法。

2.创建视图类 使用GUI库

(如Swing或JavaFX)创建一个视图类,负责呈现模型数据给用户,并接收用户的输入。

3.创建控制器类

创建一个控制器类,负责处理用户的输入和相应的操作。控制器通过监听视图的事件,并调用模型的相应方法来执行操作。

4.建立模型和视图的关联

在控制器类中,将模型和视图关联起来。通过控制器,将模型的数据传递给视图,并更新视图以反映模型的变化。

5.运行应用程序 创建一个主类

,用于启动应用程序。在主类中,实例化模型、视图和控制器,并建立它们之间的关联。

三、自定义MVC框架的应用场景

自定义MVC框架适用于需要在Java应用程序中实现清晰分离模型、视图和控制器的场景。它具有以下几个应用场景:

Web开发

自定义MVC框架可以用于开发Web应用程序,实现页面、控制器和模型的分离。控制器接收来自页面的请求,根据请求调用相应的模型和视图。

桌面应用程序

自定义MVC框架同样适用于开发桌面应用程序。通过聚合模型、视图和控制器,实现清晰的逻辑和用户界面的分离。

移动应用程序

在移动应用程序开发中,同样可以采用自定义MVC框架。通过将模型、视图和控制器分开,实现应用程序的灵活和可扩展性。

四、自定义MVC框架的优点与注意事项

优点

模块化:自定义MVC框架可以实现模块化的开发,不同部分的修改不会对其他部分产生影响。

可扩展性:通过添加新的模型、视图或控制器,可以轻松扩展应用程序的功能。 可维护性:将应用程序分解为三个组件,使得代码更易于理解、维护和测试。

注意事项

控制器的职责:控制器的职责是协调模型和视图的交互,应尽量避免在控制器中实现过多的业务逻辑。

视图的独立性:视图应尽量保持独立性,不依赖于特定的模型或控制器。

五.通过简单的代码比较突出MVC架构的优势

1.版本1

前言

版本1通过4个servlet实现增删改查

package com.niyin.com;
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;
/**
 * Servlet implementation class Bookservlet
 */
@WebServlet("/Bookservletadd")
public class Bookservletadd extends HttpServlet {
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  this.doPost(request, response);
  }
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("bookadd");
  }
}
package com.niyin.com;
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;
/**
 * Servlet implementation class Bookservlet
 */
@WebServlet("/Bookservletdel")
public class Bookservletdel extends HttpServlet {
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  this.doPost(request, response);
  }
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("bookdel");
  }
}
package com.niyin.com;
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;
/**
 * Servlet implementation class Bookservlet
 */
@WebServlet("/Bookservletlist")
public class Bookservletlist extends HttpServlet {
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  this.doPost(request, response);
  }
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("booklist");
  }
}
package com.niyin.com;
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;
/**
 * Servlet implementation class Bookservlet
 */
@WebServlet("/Bookservletupd")
public class Bookservletupd extends HttpServlet {
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  this.doPost(request, response);
  }
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("bookupd");
  }
}

jsp代码:

<%@ 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>Insert title here</title>
</head>
<body>
<p>版本1</p>
<a href="Bookservletadd">增加</a>
<a href="Bookservletupd">修改</a>
<a href="Bookservletdel">减少</a>
<a href="Bookservletlist">查询</a>
</body>
</html>

jsp运行结果

控制台输出

总结

弊端 要写4个servlet,很麻烦,代码量多

2.版本2

通过if语句优化代码,只使用一个servlet

package com.niyin.com;
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("/bookservlet")
public class bookservlet extends HttpServlet {
  private static final long serialVersionUID = 1L;
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  this.doPost(request, response);
  }
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  String methoed = request.getParameter("methodName");
  if ("add".equals(methoed)) {
    add(request,response);
  }else if("del".equals(methoed)) {
    del(request,response);
  }else if("upd".equals(methoed)) {
    upd(request,response);
  }else if("list".equals(methoed)) {
    list(request,response);
  }
  private void list(HttpServletRequest request, HttpServletResponse response) {
    // TODO Auto-generated method stub
    System.out.println("list");
  }
  private void del(HttpServletRequest request, HttpServletResponse response) {
    // TODO Auto-generated method stub
    System.out.println("del");
  }
  private void upd(HttpServletRequest request, HttpServletResponse response) {
    // TODO Auto-generated method stub
    System.out.println("upd");
  }
  private void add(HttpServletRequest request, HttpServletResponse response) {
    // TODO Auto-generated method stub
    System.out.println("add");
  }
}

jsp运行结果

控制台输出

但是每一次增加表和新的事件,都要多写if语句分支,显得代码很不必要

3. 版本3

通过反射读取方法,减少if判断

package com.niyin.com;
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("/bookservlet")
public class bookservlet extends HttpServlet {
  private static final long serialVersionUID = 1L;
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  this.doPost(request, response);
  }
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  String methoed = request.getParameter("methodName");
//  
//  if ("add".equals(methoed)) {
//    add(request,response);
//  }else if("del".equals(methoed)) {
//    del(request,response);
//
//    
//  }else if("upd".equals(methoed)) {
//    upd(request,response);
//
//    
//  }else if("list".equals(methoed)) {
//    
//    list(request,response);
//
//  }
//  
//  
  try {
    Method m = this.getClass().getDeclaredMethod(methoed, HttpServletRequest.class);
    m.setAccessible(true);
    m.invoke(this, request,response);
  } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
  }
  private void list(HttpServletRequest request, HttpServletResponse response) {
    // TODO Auto-generated method stub
    System.out.println("list");
  }
  private void del(HttpServletRequest request, HttpServletResponse response) {
    // TODO Auto-generated method stub
    System.out.println("del");
  }
  private void upd(HttpServletRequest request, HttpServletResponse response) {
    // TODO Auto-generated method stub
    System.out.println("upd");
  }
  private void add(HttpServletRequest request, HttpServletResponse response) {
    // TODO Auto-generated method stub
    System.out.println("add");
  }
}

jsp:

<%@ 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>Insert title here</title>
</head>
<body>
<p>版本1</p>
<a href="Bookservletadd">增加</a>
<a href="Bookservletupd">修改</a>
<a href="Bookservletdel">减少</a>
<a href="Bookservletlist">查询</a>
 <p>版本2</p>
<a href="Bookservletadd?methodName=add">增加</a>
<a href="Bookservletupd?methodName=upd">修改</a>
<a href="Bookservletdel?methodName=del">减少</a>
<a href="Bookservletlist?methodName=list">查询</a>
<p>版本3</p>
<a href="Bookservletadd?methodName=add">增加</a>
<a href="Bookservletupd?methodName=upd">修改</a>
<a href="Bookservletdel?methodName=del">减少</a>
<a href="Bookservletlist?methodName=list">查询</a>
</body>
</html>

控制台输出

虽然通过反射减少代码,但是增加类和表的时候,依然要多写servlet的

4.版本4Mvc版,通过子实现类Action和DispatherServlet中央控制器实现

DispatherServlet:通过获取uri,再截取里面的参数,存入map集合中,再通过键值对的方式寻找到所需要的类,通过初始化init,先把对象放入
使它得以快速寻找到对象
package com.niyin.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.niyin.com.BookAction;
@WebServlet("*.action")
public class DispatherServlet extends HttpServlet {
  public Map<String, Action> actionMap=new HashMap<String, Action>();
  @Override
  public void init() throws ServletException {
  actionMap.put("/book", new BookAction());
//  actionMap.put("/cat", new CatAction());
  }
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  this.doPost(request, response);
  }
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  String uri = request.getRequestURI(); 
  uri=uri.substring(uri.lastIndexOf("/"),uri.lastIndexOf("."));
  Action action = actionMap.get(uri);
  action.excute(request, response);
  }
}

action:子实现对象封装了反射方法,减少了servlet的代码量,servlet只需要继承action既可以使用

package com.niyin.framework;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Action {
  protected void excute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String methoed = request.getParameter("methodName");
    try {
      Method m = this.getClass().getDeclaredMethod(methoed, HttpServletRequest.class);
      m.setAccessible(true);
      m.invoke(this, request,response);
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  } 
}

servlet只需要写相关的方法即可,其它的前面两个类已经处理好了。

package com.niyin.com;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.niyin.framework.Action;
public class BookAction extends Action {
  private void list(HttpServletRequest request, HttpServletResponse response) {
    // TODO Auto-generated method stub
    System.out.println("list");
  }
  private void del(HttpServletRequest request, HttpServletResponse response) {
  // TODO Auto-generated method stub
  System.out.println("del");
}
private void upd(HttpServletRequest request, HttpServletResponse response) {
  // TODO Auto-generated method stub
  System.out.println("upd");
}
private void add(HttpServletRequest request, HttpServletResponse response) {
  // TODO Auto-generated method stub
  System.out.println("add");
}
}

jsp页面

控制台输出

总结,通过比较Mvc是最简洁,最方便的,从代码量还是思维来说都比前面的好。

打包好的文件,需要自行下载

目录
相关文章
|
5天前
|
Java 开发者
重学Java基础篇—Java类加载顺序深度解析
本文全面解析Java类的生命周期与加载顺序,涵盖从加载到卸载的七个阶段,并深入探讨初始化阶段的执行规则。通过单类、继承体系的实例分析,明确静态与实例初始化的顺序。同时,列举六种触发初始化的场景及特殊场景处理(如接口初始化)。提供类加载完整流程图与记忆口诀,助于理解复杂初始化逻辑。此外,针对空指针异常等问题提出排查方案,并给出最佳实践建议,帮助开发者优化程序设计、定位BUG及理解框架机制。最后扩展讲解类加载器层次与双亲委派机制,为深入研究奠定基础。
25 0
|
4天前
|
存储 设计模式 Java
重学Java基础篇—ThreadLocal深度解析与最佳实践
ThreadLocal 是一种实现线程隔离的机制,为每个线程创建独立变量副本,适用于数据库连接管理、用户会话信息存储等场景。
30 5
|
5天前
|
存储 监控 安全
重学Java基础篇—类的生命周期深度解析
本文全面解析了Java类的生命周期,涵盖加载、验证、准备、解析、初始化、使用及卸载七个关键阶段。通过分阶段执行机制详解(如加载阶段的触发条件与技术实现),结合方法调用机制、内存回收保护等使用阶段特性,以及卸载条件和特殊场景处理,帮助开发者深入理解JVM运作原理。同时,文章探讨了性能优化建议、典型异常处理及新一代JVM特性(如元空间与模块化系统)。总结中强调安全优先、延迟加载与动态扩展的设计思想,并提供开发建议与进阶方向,助力解决性能调优、内存泄漏排查及框架设计等问题。
25 5
|
4天前
|
机器学习/深度学习 人工智能 Java
Java机器学习实战:基于DJL框架的手写数字识别全解析
在人工智能蓬勃发展的今天,Python凭借丰富的生态库(如TensorFlow、PyTorch)成为AI开发的首选语言。但Java作为企业级应用的基石,其在生产环境部署、性能优化和工程化方面的优势不容忽视。DJL(Deep Java Library)的出现完美填补了Java在深度学习领域的空白,它提供了一套统一的API,允许开发者无缝对接主流深度学习框架,将AI模型高效部署到Java生态中。本文将通过手写数字识别的完整流程,深入解析DJL框架的核心机制与应用实践。
22 2
|
5天前
|
安全 IDE Java
重学Java基础篇—Java Object类常用方法深度解析
Java中,Object类作为所有类的超类,提供了多个核心方法以支持对象的基本行为。其中,`toString()`用于对象的字符串表示,重写时应包含关键信息;`equals()`与`hashCode()`需成对重写,确保对象等价判断的一致性;`getClass()`用于运行时类型识别;`clone()`实现对象复制,需区分浅拷贝与深拷贝;`wait()/notify()`支持线程协作。此外,`finalize()`已过时,建议使用更安全的资源管理方式。合理运用这些方法,并遵循最佳实践,可提升代码质量与健壮性。
18 1
|
11天前
|
前端开发 Java 数据库连接
Spring MVC 扩展和SSM框架整合
通过以上步骤,我们可以将Spring MVC扩展并整合到SSM框架中。这个过程包括配置Spring MVC和Spring的核心配置文件,创建控制器、服务层和MyBatis的Mapper接口及映射文件。在实际开发中,可以根据具体业务需求进行进一步的扩展和优化,以构建更加灵活和高效的企业级应用程序。
24 5
|
19天前
|
传感器 监控 Java
Java代码结构解析:类、方法、主函数(1分钟解剖室)
### Java代码结构简介 掌握Java代码结构如同拥有程序世界的建筑蓝图,类、方法和主函数构成“黄金三角”。类是独立的容器,承载成员变量和方法;方法实现特定功能,参数控制输入环境;主函数是程序入口。常见错误包括类名与文件名不匹配、忘记static修饰符和花括号未闭合。通过实战案例学习电商系统、游戏角色控制和物联网设备监控,理解类的作用、方法类型和主函数任务,避免典型错误,逐步提升编程能力。 **脑图速记法**:类如太空站,方法即舱段;main是发射台,static不能换;文件名对仗,括号要成双;参数是坐标,void不返航。
45 5
|
10天前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
56 29
|
7天前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
26 3
|
9天前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

推荐镜像

更多