引言:
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是最简洁,最方便的,从代码量还是思维来说都比前面的好。