一.MVC设计模式
概念:
MVC(Model-View-Controller)是一种常用的软件设计模式,用于组织和管理应用程序的代码。它将应用程序分为三个主要部分:模型(Model)、视图(View)和控制器(Controller),各司其职,相互之间有明确的分工。
解释:
模型(Model):模型是应用程序的数据和业务逻辑的核心部分。它负责处理数据的存取、操作和验证,以及执行业务规则。模型通常包括数据对象、数据库交互、文件操作等。它可以从数据库、文件或其他数据源中获取数据,并对数据进行操作和更新。模型不依赖于视图和控制器,可以在不改变其他部分的情况下进行独立的测试和修改。
视图(View):视图是应用程序的用户界面,负责展示数据给用户,并接收用户的输入。视图可以是图形界面、网页、命令行界面等,根据具体的应用场景而定。视图通常从模型中获取数据,并将其呈现给用户。它可以将用户的操作发送给控制器进行处理。
控制器(Controller):控制器是模型和视图之间的桥梁,负责接受用户的输入并做出相应的响应。它从视图接收用户的操作,然后根据具体的业务逻辑调用模型进行数据处理,最后将处理结果返回给视图进行展示。控制器还可以根据需要更新模型或视图。控制器的存在使得模型和视图可以独立于对方进行修改和测试。
好处 :
模块化:MVC将应用程序分为不同的部分,使每个部分都独立于其他部分。这样可以提高代码的可读性、可测试性和可维护性。
分工明确:不同的角色负责不同的任务,使开发人员能够更好地协作,提高开发效率。
可扩展性:由于MVC遵循松耦合的原则,因此可以更容易地添加新的模型、视图和控制器,以满足应用程序的新需求。
可重用性:模型、视图和控制器之间的分离使得它们可以在不同的应用程序中重用,提高代码的复用性。
二.利用XML和反射优化MVC架构
1.步骤
(1).编写ConfigModel模型存放子控制器
(2).利用init方法初始化configModel对象
(3).通过uri获取ConfigModel中的属性(path)
(4)通过path获取到type
(5).再利用它反射获取到forward
package com.YU.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.YU.framework.model.ActionModel; import com.YU.framework.model.ConfigModel; import com.YU.framework.model.ConfigModelFactory; import com.YU.web.BookAction; import com.YU.web.OrderAction; /** * ActionServlet:中央控制器 * * @author 21879 * */ @WebServlet("*.action") public class DispatherServlet extends HttpServlet { // 定义ConfigModel存放子控制器 private ConfigModel configModel; // 初始化configModel @Override public void init() throws ServletException { try { // configModel包含了所有的子控制器 configModel = ConfigModelFactory.build(); } catch (Exception e) { e.printStackTrace(); } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String uri = req.getRequestURI(); uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf(".")); // 通过uri获取到ConfigModel中的path ActionModel actionmodel = configModel.pop(uri); // 判断配置XML时是否配置了path if (actionmodel == null) throw new RuntimeException("action not config"); String type = actionmodel.getType(); // 获取到type后利用反射获取到它的forward Action action; try { action = (Action) Class.forName(type).newInstance(); action.execute(req, resp); } catch (Exception e) { e.printStackTrace(); } } }
注:在获取XML配置时需要判断是否配置当前属性
三.结果集页面配置
步骤:
1.修改子控制器的方法的返回值,将结果对象返回
package com.YU.framework; import java.lang.reflect.Method; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 子控制器,向浏览器发送请求 * @author 21879 * */ public class Action { public String execute(HttpServletRequest req,HttpServletResponse resp) { //获取请求参数 String methodName = req.getParameter("methodName"); String res = ""; try { Method m = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class); m.setAccessible(true); res = (String) m.invoke(this, req,resp); } catch (Exception e) { e.printStackTrace(); } return res; } }
2.将继承子控制器的方法的返回值修改成和子控制器一样的类型
3.获取业务代码返回值
//具体业务代码的返回值 String res = action.execute(req, resp);
4.通过返回值判断是重定向还是转发
//通过返回值判断结果是重定向还是转发 ForwardModel forwardModel = actionmodel.pop(res); if(forwardModel!=null) { boolean redirect = forwardModel.isRedirect(); //获取要跳转的页面 String path = forwardModel.getPath(); if(redirect) { resp.sendRedirect(req.getContextPath()+ path); }else { req.getRequestDispatcher(path).forward(req, resp); } } } catch (Exception e) { e.printStackTrace(); }
注意点:
1.增删改是重定向,转发会导致表单重复提交,导致数据重复操作紊乱
查询使用转发,刷新数据快,效率高
2.在重定向跳转页面的时候会导致路径错误,项目丢失
解决措施:在要跳转的Path前面加上req.getContextPath()
package com.YU.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.YU.framework.model.ActionModel; import com.YU.framework.model.ConfigModel; import com.YU.framework.model.ConfigModelFactory; import com.YU.framework.model.ForwardModel; import com.YU.web.BookAction; import com.YU.web.OrderAction; /** * ActionServlet:中央控制器 * * @author 21879 * */ @WebServlet("*.action") public class DispatherServlet extends HttpServlet { // 定义ConfigModel存放子控制器 private ConfigModel configModel; // 初始化configModel @Override public void init() throws ServletException { try { // configModel包含了所有的子控制器 configModel = ConfigModelFactory.build(); } catch (Exception e) { e.printStackTrace(); } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String uri = req.getRequestURI(); uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf(".")); // 通过uri获取到ConfigModel中的path ActionModel actionmodel = configModel.pop(uri); // 判断配置XML时是否配置了path if (actionmodel == null) throw new RuntimeException("action not config"); String type = actionmodel.getType(); // 获取到type后利用反射获取到它的forward Action action; try { action = (Action) Class.forName(type).newInstance(); //具体业务代码的返回值 String res = action.execute(req, resp); //通过返回值判断结果是重定向还是转发 ForwardModel forwardModel = actionmodel.pop(res); if(forwardModel!=null) { boolean redirect = forwardModel.isRedirect(); //获取要跳转的页面 String path = forwardModel.getPath(); if(redirect) { resp.sendRedirect(req.getContextPath()+ path); }else { req.getRequestDispatcher(path).forward(req, resp); } } } catch (Exception e) { e.printStackTrace(); } } }
四.优化参数封装
1.获取表中类属性对象
(1)创建模型驱动接口
package com.YU.framework; /** * 模型驱动接口 * @author 21879 * * @param <T> */ public interface ModelDriver<T> { T getModel(); }
2.获取到所有参数及参数req,getParamenterMap()
action = (Action) Class.forName(type).newInstance(); //判断bookAction有没有实现ModelDriver接口 if(action instanceof ModelDriver) { ModelDriver md = (ModelDriver) action; Object bean = md.getModel(); }
3.将参数值封装到表对应的对象中
//利用Spring工具类将值和键存放到map集合中 BeanUtils.populate(bean, req.getParameterMap());
注意点:
1.利用map集合将属性和值存储到模型对象中
2.要判断模型对象是否存在
五.什么是框架
一、什么是框架?
框架(Framework)是一个框子——指其约束性,也是一个架子——指其支撑性。
IT语境中的框架,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构。在此结构上可以根据具体问题扩展、安插更多的组成部分,从而更迅速和方便地构建完整的解决问题的方案。
1)框架本身一般不完整到可以解决特定问题,但是可以帮助您快速解决特定问题;没有框架所有的工作都从零开始做,有了框架,为我们提供了一定的功能,我们就可以在框 架的基础上开发,极大的解放了生产力。不同的框架,是为了解决不同领域的问题。一定要为了解决问题才去学习框架。
2)框架天生就是为扩展而设计的;
3)框架里面可以为后续扩展的组件提供很多辅助性、支撑性的方便易用的实用工具(utilities),也就是说框架时常配套了一些帮助解决某类问题的库(libraries)或工具(tools)。java中就是一系列的jar包,其本质就是对jdk功能的扩展。