一.MVC框架
1.1什么是MVC框架?
1.1.1 在Java中,MVC(Model-View-Controller)是一种常见的软件架构模式,用于组织和管理应用程序的代码。MVC框架将应用程序分为三个主要组件:模型(Model)、视图(View)和控制器(Controller)。
- 模型(Model):模型是应用程序的数据和业务逻辑的表示。它负责处理数据的读取、存储和更新,并且可以包含一些与数据相关的操作和验证。模型通常封装了应用程序的数据结构,以及对数据的访问和操作方法。
- 视图(View):视图是用户界面的表示,负责展示数据给用户。它可以是一个图形界面、一个网页或是其他形式的用户界面组件。视图通常从模型中获取数据,并将其展示给用户。视图可以被用户交互操作,并将用户的输入传递给控制器。
- 控制器(Controller):控制器负责处理用户的输入和事件,并根据输入和事件改变模型和视图。它接收来自用户界面的输入,并根据输入对模型进行操作,然后更新视图以反映这些操作的结果。控制器充当模型和视图之间的协调者,帮助管理应用程序的逻辑流程。
1.2MVC框架有什么作用?
1.2.1MVC框架的设计目标是将应用程序的不同方面分离开来,使得代码更易于维护和扩展。它可以提高应用程序的可重用性和可测试性,并允许团队在开发过程中更好地协作。适应新技术和需求。(简单来讲就是我们每个人利用自己的特长做不同的事情,每个人做的事情结合起来实现需求效果。)
1.3自定义MVC框架的原理:
注意:(1)ActionServlet(中央控制器)不做具体的业务逻辑哦,只是接收请求。
(2)Action(抽象子控制器)完成具体的业务逻辑
(3)Model()继承抽象子控制器,(负责具体实施)
(4)不能跨层调用;(客户不能直接找后台)
(5)只能由上往下进行调用;View -> Controller -> Model
1.4如果没有使用MVC自定义框架,那么我们会怎么编写代码呢?
1.4.1首先得在WebContent下创建jsp页面
以下是我写的代码:
1.4.2jsp1
<%@ 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> <pre>这是低版本mvc,4个功能跳转4个servlet</pre> <a href="AddBook.action?name=新增">新增</a> <a href="DelBook.action?name=删除">删除</a> <a href="UpdBook.action?name=修改">修改</a> <a href="LookBook.action?name=查看">查看</a> <hr style="color: red"> </body> </html>
jsp2
<%@ 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> <h3> 恭喜您点击了【<%=request.getParameter("name")%>】的操作成功! </h3> </body> </html>
方式(一)这需要4个servlet来实现(代码)
问题是4个功能跳转4个servlet。代码十分繁琐。
方式(二)这需要1个servlet来实现(代码)(减少servlet类)
一个servlet实现4个功能的代码
package com.lya.servlet; 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实现四个servlet * @author :JAVA-李永安 * @date :2023年6月29日 下午8:29:41 */ @WebServlet("/Book.action") 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 { // 将输出转换为中文 request.setCharacterEncoding("UTF-8"); // 设置输出为中文 response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); // 获取参数 String name = request.getParameter("name"); //判断点击的操作是那一步 if(name.equals("新增")) { request.getRequestDispatcher("/index2.jsp").forward(request, response); }else if(name.equals("删除")){ request.getRequestDispatcher("/index2.jsp").forward(request, response); }else if(name.equals("修改")){ request.getRequestDispatcher("/index2.jsp").forward(request, response); }else if(name.equals("查看")){ request.getRequestDispatcher("/index2.jsp").forward(request, response); } // 登录验证信息 if (!name.equals(null)) { // 如果验证成功,则转发succeed.jsp页面,并在页面显示用户名 request.getRequestDispatcher("/index2.jsp").forward(request, response); } else { // 如果验证失败,则重定向到登录页面 response.sendRedirect("/index.jsp"); } } }
方式(三)这需要1个servlet来实现(代码)(优化if语句)
package com.lya.servlet; import java.io.IOException; import java.lang.reflect.InvocationTargetException; 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; /** * 这是进阶版本mvc,4个功能跳转一个servlet,优化if语句 * @author :JAVA-李永安 * @date :2023年6月29日 下午8:29:41 */ @WebServlet("/Book.action") public class BookServlet2 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 { // 将输出转换为中文 request.setCharacterEncoding("UTF-8"); // 设置输出为中文 response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); // 获取参数 String name = request.getParameter("name"); // 判断点击的操作是那一步 // 实例类类(this指的是当前的servlet) try { Method mm = this.getClass().getDeclaredMethod(name, HttpServlet.class); mm.setAccessible(true); mm.invoke(this, request,response); } catch (NoSuchMethodException | SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 登录验证信息 if (!name.equals(null)) { // 如果验证成功,则转发succeed.jsp页面,并在页面显示用户名 request.getRequestDispatcher("/index2.jsp").forward(request, response); } else { // 如果验证失败,则重定向到登录页面 response.sendRedirect("/index.jsp"); } } }
1.5怎么实现MVC框架?
分析思路:
首先我们得清楚知道MVC框架的底层原理,我们通过浏览器访问数据或者功能,通过某种方式获取到我们所要实现的功能到中央控制器(所有的请求都会到这),通过中央控制器去识别我们的请求对象,将这些请求分发给他的下一级子控制器,再通过子控制器给他的下一级(具体的实现功能的方法),最后将我们的数据回显到指定的位置。
如果以上的思路还是有些不明白的,我再举一个生活上的实例思路:
假设朱同学想要去五星级酒店开个豪华房间,首先他得在手机上预约或者直接去酒店(发送请求给中央处理器),这是他就得找前台办理手续(识别处理对象传递信息给指定的子类,为啥要有这个子类,因为不止一个客户,也不止只是住豪华房间),接下来前台就得去根据客户需求查询对应的房间(Model所作的事情),最后告诉客户是否有对应的房间(回显需求)(相信这个思路大家是很能接收的。)
具体实现的步骤:
ActionServlet类:1.首先获取请求路径名,2.根据路径名截取到对应的请求,3.根据请求获取到对应的子控制器Action,4.将对应的请求交个对应的具体的子控制器处理。
具体实现的代码:
package com.lya.farmework; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.lya.web.BookAction; /** * 中央控制层 * * @author :JAVA-李永安 * @date :2023年6月29日 下午7:35:03 */ @WebFilter("*.action") public class Dispatherservlet extends HttpServlet { private static final long serialVersionUID = 1L; // 定以Map接收请求 public Map<String, Action> actionMap = new HashMap<String, Action>(); @Override public void init() throws ServletException { actionMap.put("/book", new BookAction()); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.首先获取请求路径名. StringBuffer requestURL = request.getRequestURL(); // 2.根据路径名截取到对应的请求. requestURL.substring(requestURL.lastIndexOf("/"), requestURL.lastIndexOf(".")); // 3.根据请求获取到对应的子控制器Action. Action action = actionMap.get(requestURL); //获取父类方法 action.excute(request, response); // 4.将对应的请求交个对应的具体的子控制器处理. } }
Action子控制类
package com.lya.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.lya.farmework.Action; /** * 具体的子控制器 * * @author :JAVA-李永安 * @date :2023年6月29日 下午7:39:52 */ public class BookAction extends Action { public void lookbook(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("查看详情"); } public void del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("删除"); } public void upd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("修改"); } public void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("新增"); } }
具体的子控制类
package com.lya.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.lya.farmework.Action; /** * 具体的子控制器 * * @author :JAVA-李永安 * @date :2023年6月29日 下午7:39:52 */ public class BookAction extends Action { public void lookbook(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("查看详情"); } public void del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("删除"); } public void upd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("修改"); } public void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("新增"); } }
二.三层架构
2.1什么是三层架构?
2.1.1 在Java开发中,三层架构(Three-Tier Architecture)是一种常见的软件架构模式,用于组织和管理应用程序的代码和组件。
三层架构将应用程序分为三个独立的逻辑层,每个层次都有不同的职责和功能。这三个层次是:
- 表示层(Presentation Layer):表示层是用户与应用程序交互的界面层。它负责接收用户的输入并显示结果。在Java中,通常使用页面、UI组件和控制器来实现表示层。表示层的主要作用是将用户界面和应用程序的业务逻辑解耦,使得界面的变化不会影响到业务逻辑的实现。
- 业务逻辑层(Business Logic Layer):业务逻辑层是应用程序的核心层,负责处理应用程序的业务逻辑。它包含了对数据的处理、业务规则的执行以及与数据持久化层的交互。在Java中,业务逻辑层通常使用Java类、接口和服务来实现。业务逻辑层与表示层和数据持久化层之间进行数据交换和协调,确保数据的正确性和一致性。
- 数据持久化层(Data Access Layer):数据持久化层负责处理数据的读取、存储和管理。它与底层数据库或其他数据存储系统进行交互,执行数据的增删改查操作。在Java中,数据持久化层通常使用ORM(对象关系映射)工具或原生的JDBC(Java数据库连接)技术来实现。数据持久化层的主要作用是将数据与业务逻辑层解耦,使得业务逻辑层不需要直接处理数据库操作。
2.2三层架构有什么作用?
在Java中,三层架构(Three-Tier Architecture)具有以下几个重要的作用和优势:
- 分离关注点:三层架构的主要目标是将不同的关注点分离开来,使得每个层次可以专注于特定的任务和责任。表示层负责交互界面的展示和用户输入的接收,业务逻辑层负责处理业务规则和流程,数据持久化层负责数据存储和管理。这种分离带来了更高的可维护性和可重用性,而且不同层次的代码可以独立进行修改和扩展,不会对其他层次产生影响。
- 提高可扩展性:三层架构可以减少不同层次之间的依赖关系,使得各个层次可以独立进行扩展。例如,如果需要改变应用程序的用户界面,只需修改表示层而不需要改变业务逻辑层或数据持久化层。这种松耦合的设计使得应用程序更容易适应变化和演化。
- 提高可测试性:三层架构将应用程序划分为独立的层次,每个层次都可以单独进行测试。这样,开发人员可以更容易地编写针对每个层次的单元测试和集成测试。同时,由于层次之间的解耦,利用模拟或桩件来隔离不同层次的测试也更加容易。这有助于提高代码的质量和可靠性。
- 简化团队合作:三层架构使得不同的开发团队可以并行开发不同的层次。每个团队可以专注于自己的领域而不需要关心其他层次的实现细节。这种分工协作可以加快开发进度,并且减少不同团队之间的协调成本。
- 提高应用程序的性能和可伸缩性:由于三层架构的分层设计,可以将不同层次的功能部署到不同的物理服务器或集群上。这种架构可以以水平扩展的方式来增加系统的容量和吞吐量,从而提高应用程序的性能和可伸缩性。
综上所述,三层架构在Java中具有良好的分层设计原则,可以提高应用程序的可维护性、扩展性、可测试性和团队协作效率。它是一种常用的架构模式,广泛应用于Java企业应用程序的开发中。
2.3怎么实现三层架构?
- 划分层次:将应用程序划分为表示层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据持久化层(Data Access Layer)。每个层次都有明确定义的职责和功能。
- 设计数据模型:定义应用程序的数据模型,包括实体(Entity)和关系数据库的表结构。根据需求和业务逻辑,确定实体之间的关系和属性。
- 开发表示层:表示层负责处理用户界面的展示和用户输入的接收。根据需求和设计,开发用户界面的页面、表单、控件等,确保用户界面能够与用户进行交互。
- 开发业务逻辑层:业务逻辑层负责处理应用程序的业务规则和流程。在该层次中,根据需求和设计,编写各种业务逻辑的代码,例如验证用户输入、处理数据逻辑、计算、安全性检查等。
- 开发数据持久化层:数据持久化层负责数据的存储和管理。在该层次中,根据需求和设计,实现与数据库的交互,包括数据的读取、写入、更新和删除等操作。可以利用ORM(对象关系映射)工具简化数据持久化的开发。
- 实现层次间的交互:不同层次之间需要进行交互和通信。例如,表示层需要调用业务逻辑层的方法来处理用户请求,业务逻辑层需要调用数据持久化层的方法来读写数据。要确保层次之间的交互合理、清晰,并且符合层次之间的关注点分离原则。
- 测试和调试:完成开发后,对不同层次的代码进行单元测试、集成测试以及整体的功能测试。确保不同层次之间的协作和功能的正确性。
- 部署和维护:将应用程序部署到生产环境中,并进行必要的配置和调优。在运行阶段,需要进行监控、优化和维护,保证应用程序的稳定运行。
需要注意的是,三层架构是一种通用的架构模式,可以根据具体的需求和项目的规定来使用
三.MVC框架与三层架构异同
3.1相同点:
- 分离关注点:MVC框架和三层架构都关注将应用程序的不同部分分离开来,使其更易于开发、测试和维护。
- 组织代码结构:两者都提供了一种组织代码结构的方式,以便更好地管理和定位不同的功能,实现代码的可读性和可维护性。
- 增强可重用性:通过分层和模块化的设计,MVC框架和三层架构都鼓励代码的可重用性,使开发者能够更好地使用现有的组件和模块。
- 降低耦合性:MVC框架和三层架构都有助于减少不同组件之间的紧耦合,使得组件之间的交互更加松散和灵活。
3.2不同点:
三层架构是一个经典的分层思想,将开发模式分为三层,每个人专注自己擅长模块即可(一对一单线连接 , 一对一的关系) MVC框架是一种设计模式,其目的是让html和业务逻辑分开(通过总的入口中央管理器去连接 , 一对多的关系)
四.总结
1.理解MVC的概念:首先,你需要对MVC的概念有一个清晰的理解。MVC是一种软件设计模式,将应用程序分为三个主要组件:模型(Model)、视图(View)和控制器(Controller)。模型负责处理数据,视图负责呈现界面,控制器负责协调模型和视图之间的交互。
2.学习自定义MVC这将帮助你更好地理解和应用MVC的设计模式,提高软件开发的质量和效率。同时,通过自定义MVC框架的学习,你还可以深入了解框架的设计和实现,以及如何构建可扩展、高效的应用程序。
好啦,今天的分享就到这了,希望能够帮到你呢!!!