J2EE之自定义MVC框架(上篇)

J2EE之自定义MVC框架知识(上篇)

前言

想必在了解自定义MVC框架知识之前,有些老铁可能学习了解过MVC三层架构。MVC三层架构和自定义MVC框架类似,但本质上有区别。接下来让我们根据思维导图来了解学习自定义MVC框架知识。

在这里插入图片描述

1.自定义MVC框架简介

1.1 什么是自定义MVC框架

1.1.1 了解MVC模式

MVC是模型-视图-控制器(Model-View-Controller)的缩写,是一种常用的软件架构模式。它将一个应用程序分为三个主要部分:模型、视图和控制器,各自有不同的职责和功能。

  1. 模型(Model):模型负责处理应用程序的数据逻辑部分,它表示应用程序的核心数据和业务规则。模型负责处理数据的增删改查等操作,与数据库或其他数据源进行交互。它是应用程序的数据存储和处理核心,并且通常包含数据的验证和处理逻辑。
  2. 视图(View):视图负责展示模型中的数据给用户,并与用户进行交互。它是用户界面的部分,负责呈现数据给用户并接受用户的输入。视图通常是以用户能够感知的形式展示数据,如网页、图形界面等。
  3. 控制器(Controller):控制器负责处理用户的输入,并根据用户的请求来更新模型和视图。它是模型和视图之间的协调者,接收用户输入或事件,根据需要更新模型的状态或数据,并将更新后的数据传递给视图进行展示。控制器还负责处理应用程序中的业务逻辑,如路由、权限校验等。
1.1.2 自定义MVC框架
  • 自定义MVC框架指的是基于模型-视图-控制器(MVC)架构模式,根据自己的需求和设计,从头开始创建的框架。
  • 自定义MVC框架指的是基于模型-视图-控制器(MVC)架构模式,根据自己的需求和设计,从头开始创建的框架。
  • 自定义MVC框架的主要目的是提供一个可扩展、可定制化的开发框架,以满足特定项目的需求。通常,自定义MVC框架允许开发者根据自己的要求来定义控制器、模型和视图的组织结构,以及它们之间的交互方式。

1.2 为什么要使用自定义mvc框架

1.2.1 三层架构与自定义MVC框架的区别

自定义MVC框架是一种设计模式,用于组织和管理应用程序的逻辑和界面部分。它将应用程序分为模型、视图和控制器三个组件,每个组件有不同的职责和功能。自定义MVC框架注重实现用户界面和业务逻辑的分离,提高代码的可维护性和可扩展性。

三层架构是一种软件架构模式,用于将应用程序的功能和组件划分为三个逻辑层:表示层、业务逻辑层和数据访问层。这种架构模式将整个应用程序划分为不同的层,每个层有不同的职责和功能。表示层负责用户界面的展示和交互,业务逻辑层负责处理应用程序的业务逻辑,数据访问层负责与数据库或其他数据源进行交互。

主要区别:

  1. 组织方式:自定义MVC框架主要关注应用程序的逻辑和界面的组织,强调模型、视图和控制器之间的分离和协作。而三层架构关注应用程序的功能和组件的组织,将应用程序划分为表示层、业务逻辑层和数据访问层,强调不同层次之间的分离和解耦。
  2. 强调点:自定义MVC框架更加注重用户界面和业务逻辑的分离,使得界面和逻辑的修改可以独立进行。而三层架构更加注重功能和数据的分离,使得不同层次的修改可以独立进行。
  3. 强调点:自定义MVC框架更加注重用户界面和业务逻辑的分离,使得界面和逻辑的修改可以独立进行。而三层架构更加注重功能和数据的分离,使得不同层次的修改可以独立进行。

注:

自定义MVC框架和三层架构并不是互斥的概念,它们可以结合使用。在实际应用中,可以采用自定义MVC框架来组织和管理用户界面和业务逻辑,同时使用三层架构来划分和管理功能和数据的组织。这样可以充分发挥两种模式的优点,提高软件的可维护性和可扩展性。

1.2.2 自定义MVC框架的作用
  • 分离关注点:自定义MVC框架帮助开发者将应用程序的不同关注点分离开来,如数据逻辑、用户界面和业务处理。
  • 解耦合:自定义MVC框架通过模型、视图和控制器之间的明确划分,减少了不同组件之间的耦合度。
  • 灵活性和可扩展性:自定义MVC框架为开发者提供了一种灵活和可扩展的框架,使其能够根据具体需求自由调整和扩展每个组件。
  • 提高代码复用性:自定义MVC框架鼓励开发者将可复用的代码封装到模型、视图和控制器中,以便在不同的应用程序中进行重用。
  • 提升开发效率:自定义MVC框架可以提供一些开发工具和功能,如路由、表单验证、错误处理等,以提升开发效率。
1.2.3 自定义MVC框架的作用的重要性
  1. 架构清晰:自定义MVC框架提供了一种清晰的架构模式,通过将应用程序分成模型、视图和控制器三个组件,使得代码的组织和结构更加清晰明了。这种清晰的架构模式可以降低代码的复杂性,提高代码的可读性和可维护性。
  2. 逻辑分离:自定义MVC框架将不同的关注点分离开来,如数据逻辑、用户界面和业务处理。这种分离使得开发者可以独立地开发和修改每个组件,从而提高了代码的可维护性。同时,这种分离也有助于团队协作,不同开发人员可以专注于不同的组件,提高开发效率。
  3. 可维护性和可扩展性:自定义MVC框架通过降低代码的耦合度和提供良好的架构模式,使得代码更加易于维护和扩展。开发者可以根据具体需求来定制框架的行为,并根据应用程序的发展来扩展模型、视图和控制器。这种可维护性和可扩展性使得应用程序更加适应变化和快速迭代。
  4. 代码复用:自定义MVC框架可以促进代码的模块化和重用。通过将通用的功能和逻辑封装到模型、视图和控制器中,开发者可以在不同的项目中重复使用这些组件,从而减少开发工作量,提高开发效率。
  5. 可测试性:自定义MVC框架可以提高代码的可测试性。通过分离关注点和提供清晰的接口,开发者可以更容易地编写和执行单元测试、集成测试等各种类型的测试。这有助于保证代码的质量和稳定性,并提供快速反馈以修复潜在的问题。

1.3 如何只用自定义MVC框架

  1. 确定框架:选择一个适合的MVC框架。常见的MVC框架有Spring MVC、ASP.NET MVC、Ruby on Rails等。根据自己熟悉的编程语言和框架来选择。
  2. 创建项目结构:根据选定的MVC框架创建项目结构。通常,框架提供了一些约定和指导,可以让你按照最佳实践来组织项目结构。
  3. 定义模型:根据应用程序需求,在模型层定义数据结构和业务逻辑。模型是负责处理应用程序的数据逻辑和业务规则的组件。
  4. 创建视图:在视图层中创建用户界面。视图是负责展示模型中的数据给用户,并与用户进行交互的组件。根据需要,可以使用HTML、CSS、JavaScript等技术来创建视图。
  5. 编写控制器逻辑:在控制器层中编写处理用户请求和更新模型的逻辑。控制器接收用户的输入或事件,根据需要调用模型的方法进行数据的处理,然后将更新后的数据传递给视图进行展示。
  6. 绑定路由:配置路由规则,将请求路由到相应的控制器和操作方法。路由规则决定了用户请求的URL与控制器的映射关系,以及调用对应的操作方法。
  7. 测试和调试:使用单元测试、集成测试等方式来测试和调试应用程序。这可以确保应用程序的正确性和稳定性。
  8. 部署和发布:将应用程序部署到服务器上,并发布给用户使用。这包括安装服务器环境、配置数据库连接等。

1.4 自定义MVC工作原理

在这里插入图片描述

2. 模拟原生实现界面数据的增删改查

2.1 编写对应增删改查四个方法的Servlet类

AddBookServlet类(新增)
package com.YX.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;

/**
 * 执行新增方法的Servlet类
 * 
 * @author 君易--鑨 2023年6月29日下午7:23:38
 * 
 */
@WebServlet("/add.do")
public class AddBookServlet 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("使用了新增方法.......");
	}
}

DelBookServlet类(删除)
package com.YX.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;

/**
 * 执行删除方法的Servlet类
 * 
 * @author 君易--鑨 2023年6月29日下午7:23:38
 * 
 */
@WebServlet("/del.do")
public class DelBookServlet 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("使用了删除方法.......");
	}

}

UpdBookServlet类(修改)
package com.YX.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;

/**
 * 执行修改方法的Servlet类
 * 
 * @author 君易--鑨 2023年6月29日下午7:23:38
 * 
 */
@WebServlet("/upd.do")
public class UpdBookServlet 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("使用了修改方法.......");
	}

}

ListBookServlet类(查看)
package com.YX.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;

/**
 * 执行显示数据方法的Servlet类
 * 
 * @author 君易--鑨 2023年6月29日下午7:23:38
 * 
 */
@WebServlet("/look.do")
public class ListBookServlet 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("使用了查看方法.......");
	}

}

2.2 编写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>模拟原生实现界面数据的增删改查</p>
<a href="add.do">新增</a>
<a href="del.do">删除</a>
<a href="upd.do">修改</a>
<a href="look.do">查看</a>

</body>
</html>

在这里插入图片描述

控制台输出结果

在这里插入图片描述

2.3 弊端

每一张表对应的每一个操作,都要重新创建一个Servlet类编写,导致代码冗余

3.模拟原生实现界面数据的增删改查(优化版)

3.1 创建编写一个BookServlet类

package com.YX.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;

/**
 * Servlet集合类 包含增删改查四个方法
 * 
 * @author 君易--鑨 2023年6月29日下午8:13:50
 * 
 */
@WebServlet("/book.do")
public class BookServlet 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 {
		// 获取页面传来的方法参数,用于辨别执行对应操作的方法
		String methodName = request.getParameter("methodname");
		// 根据获取的方法参数做判断执行对应操作
		if (methodName.equals("add")) {// 新增
			add(request, response);
		} else if (methodName.equals("del")) {// 删除
			del(request, response);
		} else if (methodName.equals("upd")) {// 修改
			upd(request, response);
		} else if (methodName.equals("list")) {// 查看
			list(request, response);
		}

	}

	/**
	 * 新增的方法
	 * 
	 * @param request
	 * @param response
	 */
	private void add(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了新增的方法........");
	}

	/**
	 * 删除的方法
	 * 
	 * @param request
	 * @param response
	 */
	private void del(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了删除的方法........");
	}

	/**
	 * 修改的方法
	 * 
	 * @param request
	 * @param response
	 */
	private void upd(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了修改的方法........");
	}

	/**
	 * 查看的方法
	 * 
	 * @param request
	 * @param response
	 */
	private void list(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了查看的方法........");

	}

}

通过编写一个总体的Servlet类包含表的增删改查四个操作方法,然后在页面选择对应操作时携带一个方法参数methodname到Servlet中,在Servlet中通过携带过来的参数做判断,根据参数来执行对应的操作。

3.2 页面测试

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>模拟原生实现界面数据的增删改查(优化版)</p>
<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=list">查看</a>
</body>
</html>

点击增删改查对应的四个按钮(页面效果就不显示了)

控制台的结果

在这里插入图片描述

3.3 弊端

写一个总的Servletl来处理客户端的请求虽然解决了类冗余,但是新增一个操作功能,总的Servlet都需要改变原有代码的代码块,换句话说方法体判断语句会增多,导致条件分支冗余。

4. 反射优化模拟原生实现界面数据的增删改查

4.1 BookServlet(优化版)

package com.YX.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;

/**
 * Servlet集合类 包含增删改查四个方法
 * 
 * @author 君易--鑨 2023年6月29日下午8:13:50
 * 
 */
@WebServlet("/book.do")
public class BookServlet 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 {
		// 获取页面传来的方法参数,用于辨别执行对应操作的方法
		String methodName = request.getParameter("methodname");
		// 反射从获取类类开始 this:代表BookServlet类
		try {
			// 获取当前类的方法对象
			Method sclass = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
			// 打开访问权限
			sclass.setAccessible(true);
			// 执行对应方法名对象的方法
			sclass.invoke(this, request, response);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 新增的方法
	 * 
	 * @param request
	 * @param response
	 */
	private void add(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了新增的方法........");
	}

	/**
	 * 删除的方法
	 * 
	 * @param request
	 * @param response
	 */
	private void del(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了删除的方法........");
	}

	/**
	 * 修改的方法
	 * 
	 * @param request
	 * @param response
	 */
	private void upd(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了修改的方法........");
	}

	/**
	 * 查看的方法
	 * 
	 * @param request
	 * @param response
	 */
	private void list(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了查看的方法........");

	}

}

4.2 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>反射优化原生实现界面数据的增删改查 </p>
<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=list">查看</a>
</body>
</html>

点击增删改查对应的四个按钮(页面效果就不显示了)

控制台输出结果

在这里插入图片描述

5.自定义MVC框架优化

5.1 创建相关的类

DispatherServlet类(中央控制器)
package com.YX.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.YX.Web.BookAction;

/**
 * 中央控制器
 * 
 * @author 君易--鑨 2023年6月29日下午10:20:15
 * 
 */
@WebServlet("*.do")
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());
		super.init();
	}

	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.execute(request, response);

	}
}

BookAction类
package com.YX.Web;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.YX.framework.Action;


/**对应表的操作方法类
 * @author 君易--鑨
 * 2023年6月29日下午10:40:48
 * 
 */
public class BookAction extends Action{
  
	/**
	 * 新增的方法
	 * 
	 * @param request
	 * @param response
	 */
	public void add(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了新增的方法........");
	}

	/**
	 * 删除的方法
	 * 
	 * @param request
	 * @param response
	 */
	public void del(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了删除的方法........");
	}

	/**
	 * 修改的方法
	 * 
	 * @param request
	 * @param response
	 */
	public void upd(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了修改的方法........");
	}

	/**
	 * 查看的方法
	 * 
	 * @param request
	 * @param response
	 */
	public void list(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("调用了查看的方法........");

	}
}

Action类(子控制器)
package com.YX.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 君易--鑨
 * 2023年6月29日下午9:48:19
 * 
 */
public class Action {
	protected void execute(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 获取页面传来的方法参数,用于辨别执行对应操作的方法
		String methodName = request.getParameter("methodname");
		// 反射从获取类类开始 this:代表BookServlet类
		try {
			// 获取当前类的方法对象
			Method sclass = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,
					HttpServletResponse.class);
			// 打开访问权限
			sclass.setAccessible(true);
			// 执行对应方法名对象的方法
			sclass.invoke(this, request, response);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}

5.2 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>自定义MVCk框架优化反射实现界面数据的增删改查  </p>
<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=list">查看</a>

</body>
</html>

点击增删改查对应的四个按钮(页面效果就不显示了)

控制台测试输出结果

在这里插入图片描述

结束语

其实我们通过自定义MVC框架实现优化还有代码可以优化,还可也减少我们的代码量,提高我们的开发效率。我将在下期博客分享如何继续优化,老铁三连,看我教你如何优化。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值