1.MVC模式
1.1 MVC是什么?
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范。用一种业务逻辑、数据、界面显示分离的方法,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
通过将应用程序的逻辑分离到不同的组件中,MVC模式提高了代码的可维护性、复用性和可测试性。它也促进了团队的协作和并行开发,因为不同的成员可以独立地开发模型、视图和控制器。许多现代的Web框架和应用程序框架都使用MVC模式作为其设计基础。
1.2 MVC结构
MVC代表模型-视图-控制器,它将应用程序的逻辑划分为三个组件:
- 模型(Model):模型表示应用程序的数据和业务逻辑。它负责管理数据的存储、检索、更新和验证,并提供与数据相关的功能。模型通常是应用程序中最基础的组件。
- 视图(View):视图是用户界面的表示。它负责将模型的数据以合适的方式呈现给用户,例如在屏幕上显示文本、图片、表格等。视图通常是根据用户的输入和模型的数据来动态更新。
- 控制器(Controller):控制器是模型和视图之间的协调者。它接收来自用户的输入,并根据这些输入更新模型和视图。控制器将用户的操作转发给模型进行处理,并根据模型的状态更新视图。控制器还可以处理应用程序中的其他逻辑,例如验证用户输入、处理错误等。
2.自定义MVC框架与MVC三层架构有什么联系与区别
自定义 MVC 框架和三层架构是两个不同的概念,但它们可以在某种程度上相互关联。下面是它们之间的联系和区别:
1.联系:
1.1分层结构:自定义 MVC 框架和三层架构都关注将应用程序分为不同的层次结构,以实现代码的组织和模块化。它们都提倡将应用程序的不同功能划分为不同的层,以实现分工协作、代码重用和易维护性。
1.2解耦和扩展性:自定义 MVC 框架和三层架构都倡导通过解耦和模块化来实现系统的扩展性。通过将应用程序的不同模块分离,可以更容易地修改、替换或添加新的功能,而不会对整个系统产生较大的影响。
2.区别:
2.1.关注点不同:自定义 MVC 框架主要关注用户界面和用户交互层面的开发,通过模型-视图-控制器的分离将应用程序的视图与业务逻辑分离开来,以实现代码的可维护性和可测试性。而三层架构主要关注数据处理和业务逻辑层面的开发,通过数据访问层、业务逻辑层和表示层的分离,实现数据的持久化和业务逻辑的处理。
2.2 框架 vs 架构:自定义 MVC 框架更加具体和具体化,它是一个针对特定用户界面和交互的框架。而三层架构是一种通用的软件架构模式,它不关注具体的技术实现,更加关注应用程序的整体结构和组织。
2.3.范围不同:自定义 MVC 框架通常只关注应用程序的前端开发,涉及用户界面和用户交互的实现。而三层架构则是一种更为全面的架构模式,它涵盖了整个应用程序的开发,并关注数据处理、业务逻辑和表示层的组织和分离。
注意,自定义 MVC 框架和三层架构可以同时应用于一个应用程序中,以实现更好的代码组织和模块化。自定义 MVC 框架可以用于前端开发,将用户界面和交互分离开来;而三层架构可以用于后端开发,将数据处理和业务逻辑分离开来。这样可以实现更清晰的代码结构和更好的代码组织
3.为什么要使用自定义MVC框架
- 1. 灵活性和定制性:自定义 MVC 框架允许根据应用程序的需求来定制框架的各个部分。您可以选择适合项目的技术栈、组件和工具,定义自己的命名规则、目录结构、路由配置等。这样可以更好地适应特定的项目需求,减少不必要的冗余和复杂性
- 2. 理解和掌控:通过自定义 MVC 框架,能更好地理解和掌控应用程序的结构和流程。您可以深入了解框架的工作原理,以及每个组件在请求处理过程中的作用。这有助于更好地调试和优化代码,同时也提高了对整个应用程序的把控能力
- 3. 可定制的路由和请求处理:自定义 MVC 框架允许您灵活控制路由和请求处理的方式。可以自定义路由规则,将不同的请求映射到相应的控制器和操作方法上,并根据需要执行预处理、数据验证、权限验证等操作。这样可以更好地控制请求的处理流程,并更好地满足特定的业务需求
- 4. 增强的代码重用性和可维护性:通过自定义 MVC 框架,可以定义通用的模块和组件,提高代码的重用性。这样可以减少重复劳动和代码冗余,并提高开发效率。同时,自定义 MVC 框架也可以通过合理的分层和组织结构来提高代码的可维护性,使代码更易于理解、测试和修改
- 5. 适应新技术和需求:自定义 MVC 框架使您更加灵活地适应新技术和需求。当新的技术出现时,可以根据需要轻松集成和应用到自定义框架中。同样,当项目需求发生变化时,也可以相应地调整框架的实现,而无需受限于现有框架的限制
4.自定义MVC工作原理
5.自定义MVC的实现(以Book.java为例实现)
5.1 根据上图,我们先定义ActionServlet 也就是中央控制器:负责接受请求,然后安排合适的servlet来执行从浏览器传来的请求
这里的步骤:
5.1.1.获取路径
5.1.2.截取 Book
5.1.3.因为要通过截取的/User 去找UserServlet,所以创建一个Map集合
5.1.4.进行初始化,将所有的Servlet添加进去
5.1.5获取
package 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.sy.BookServlet; @WebServlet("*.servlet") public class ActionServlet extends HttpServlet{ //因为要通过截取的/User 去找UserServlet,所以创建一个Map集合 Map<String, Action> actionMap=new HashMap<String, Action>(); //进行初始化,将所有的Servlet添加进去 @Override public void init() throws ServletException { actionMap.put("/User", new BookServlet()); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException{ //http://localhost:8080/MVC/User.jsp //获取路径,截取 User 目的是为了知道需要调用哪个servlet里的方法 //1.获取路径 String uri = req.getRequestURI(); //2.截取 User uri=uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));//截取的结果为:/User //5.获取 System.out.println(uri); Action action = actionMap.get(uri); //调取 action.execute(req, resp); } }
5.2 控制器(Controller)
然后建立一个Action类,它是子控制器,负责处理从浏览器传来的请求 ,是其他类增删改查类的父类,它去调浏览器请求的方法,所有这里运用到反射 来处理请求,通过它来调相应Servlet,它需要从获取前端的参数,来判断要调用哪个方法。
package framework; import java.io.IOException; import java.lang.reflect.Method; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 子控制器:是其他类增删改查类的父类,它去调浏览器请求的方法,所有这里运用到反射 * 来处理请求,通过它来调相应Servlet * @author 86177 * */ public class Action { protected void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取参数methodName String methodName = req.getParameter("methodName"); try { Method m = this.getClass().getDeclaredMethod(methodName,HttpServletRequest.class,HttpServletResponse.class); //打开访问权限 m.setAccessible(true); m.invoke(this, req,resp); } catch (Exception e) { e.printStackTrace(); } } }
5.3 写增删改查的具体的方法类
package com.sy; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import framework.Action; public class BookServlet extends Action{ public void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("BookAddServlet.add..增加."); } public void del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("BookAddServlet.del..删除."); } public void upd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("BookAddServlet.upd..修改."); } public void query(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("BookAddServlet.list..查看."); } }
5.4 视图(view) 展示的那个类
6.效果展示: