目录
一、什么是MVC?
1.模型(Model):
2.视图(View):
3.控制器(Controller):
二、自定义mvc核心思想
三、自定义MVC的核心原则
四、 三层架构和MVC的区别
1.结构层次不同:
2.重点关注不同:
3.强调的功能不同
4.可扩展性和复用性不同:
五、MVC工作原理
举个栗子:
六、MVC结构对应关系
1.模型-视图对应关系:
2.控制器-视图对应关系:
3.控制器-模型对应关系:
七.优缺点
优点:
缺点:
八、自定义mvc的简单实现
1.中央控制器
2.Action类定义
3.继承子控制器
4.完善中央控制器
1.请求分发功能
2.action子控制器
3.请求参数处理功能
一、什么是MVC?
MVC代表模型-视图-控制器,是一种经典的软件设计模式,常用于构建桌面应用程序、Web应用程序和移动应用程序。它将一个应用程序分为三个主要部分:
1.模型(Model):
负责处理应用程序的数据逻辑和状态管理。它包含数据模型和业务逻辑,可以访问、操作和更新数据。
2.视图(View):
负责展示和呈现数据给用户,通常是用户界面的组件。它根据模型的数据来渲染界面,提供用户与应用程序交互的界面。
3.控制器(Controller):
充当模型和视图之间的中介,处理用户的输入和响应。它接收用户的动作并更新模型和视图的状态,确保它们保持同步。
二、自定义mvc核心思想
自定义MVC架构的核心思想是将应用程序的不同功能部分分离开来,以实现更好的代码组织、可维护性和可扩展性。虽然MVC的基本架构已经定义了模型、视图和控制器,但是具体实现和组织方式可以根据项目的需求进行自定义。
三、自定义MVC的核心原则
-
核心组件分离: 保持模型、视图和控制器的独立性,每个组件都应该专注于自己的领域。模型负责数据处理和业务逻辑,视图负责展示界面,而控制器负责处理用户输入和协调其他组件。
-
清晰的通信接口: 定义清晰的接口和协议,以确保模型、视图和控制器之间的通信和交互是统一和可预测的。这可以减少耦合性,使组件更容易替换和扩展。
-
事件驱动: 引入事件驱动的思想可以提高MVC架构的灵活性和响应性。组件之间可以通过事件来进行通信,而不是直接调用方法。这样可以减少依赖关系,使系统更能适应变化。
-
分层架构: 根据应用程序的规模和复杂性,可以将MVC架构进一步分层。例如,可以引入服务层或数据访问层来处理特定的功能和访问外部资源,从而实现更好的代码分离和职责划分。
-
可测试性和可扩展性: 考虑如何设计MVC架构以便于测试和扩展。确保模型、视图和控制器的可测试性,以便能够进行单元测试和集成测试。同时,提供灵活的扩展点和插件机制,使新功能的添加和变更更加容易。
四、 三层架构和MVC的区别
1.结构层次不同:
- 三层架构:将应用程序划分为表示层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access Layer)。
- MVC:将应用程序划分为模型(Model)、视图(View)和控制器(Controller)。模型和视图负责应用程序的数据和界面,控制器负责处理用户输入和协调模型和视图之间的交互。
2.重点关注不同:
- 三层架构:着重于将应用程序按照功能职责进行分层,将关注点分离,并提供更好的可维护性和可扩展性。
- MVC:着重于将应用程序按照数据、界面和交互逻辑进行分离,实现用户界面和数据逻辑的解耦,并提供更好的用户体验和可重用性。
3.强调的功能不同
- 三层架构:着重于数据的管理和持久化,业务逻辑的封装和处理,以及用户界面的展示和交互。
- MVC:着重于界面的设计和呈现,用户交互的处理和响应,以及数据模型的管理和更新。
4.可扩展性和复用性不同:
- 三层架构:通过明确的层次划分和职责分离,提供更好的可扩展性和模块化设计,使不同层级的组件可以独立地进行调整和替换。
- MVC:通过分离数据逻辑、界面和交互逻辑,提供更好的复用性和可维护性,使视图和控制器可以被重用于不同的模型和业务逻辑。
五、MVC工作原理
举个栗子:
比如说一个老板他开饭店,刚开始为了节约成本,他一个人做事,从早上起床买菜、洗菜、切菜,切完之后有客人来了、还要招呼客人,客人还要点单点完单之后又要去炒菜,这一系列下来都是他一个人做的,客人吃完之后他还要洗碗,前期当他店小的时候用户量小的情况下他一个人是可以做的到的。
但是当他后期生意越来越好,想扩展规模越来越大的时候,他一个人就做不了这些事情了。
此时只能请人分配各个岗位,老板就做管理,管理员工。(各司其职)
六、MVC结构对应关系
1.模型-视图对应关系:
- 模型(Model):负责封装应用程序的数据和业务逻辑。
- 视图(View):负责展示模型中的数据给用户。
在这个对应关系中,模型代表应用程序的数据和操作方法,它存储和管理数据,并提供与数据相关的操作。视图是用户界面的表示部分,它负责展示模型中的数据给用户,通常是以可视化的形式呈现,如HTML页面、图表、列表等。
2.控制器-视图对应关系:
- 控制器(Controller):负责接收用户的输入和请求,并根据请求的类型和参数选择合适的视图进行展示。
- 视图(View):负责接收控制器传递的数据并将其呈现给用户。
这个对应关系中,控制器充当了视图和模型之间的协调者和中介者。它接收用户的输入或请求,并根据请求对模型进行操作。一旦模型处理完成后,控制器选择适当的视图进行展示,将模型中的数据传递给视图进行渲染。
3.控制器-模型对应关系:
- 控制器(Controller):负责接收用户的输入和请求,并根据请求的类型和参数选择相应的模型进行处理。
- 模型(Model):负责处理数据逻辑和状态管理。
这个对应关系中,控制器负责接收用户的输入,根据输入的请求调用适当的模型来处理数据逻辑和状态管理。控制器根据模型的处理结果来决定下一步的行动,可以进行数据更新、查询、保存等操作。
术语 |
对应关系 |
M |
实体域模型(名词)entity,过程域模型(动词:因为是可变的)dao/biz |
V |
jsp |
C |
servlet/action |
七.优缺点
优点:
耦合性低
重用性高
生命周期成本低
可维护性高
部署快
缺点:
1.增加系统结构和实现的复杂性
对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。
2.一般高级的界面工具或构造器不支持模式
改造这些工具以适应MVC需要和建立分离的部件的代价是很高的,会造成MVC使用的困难。
细讲原理图:
1.ActionServlet:中央控制层
2.子控制器Action中央控制器就是老板用来做管理的,子控制器就是各个员工,具体做事的那个人就叫子控制器。
注意:子控制器必须获取资格证才能上岗做事,这个资格证相当于Action
它里面有一个execute方法(处理具体逻辑)
八、自定义mvc的简单实现
1.中央控制器
通过servlet来实现一个中央控制器,负责所有请求的接收。(后续中央控制器在再将请求转发给各个子控制器,此处可以先把请求接进来,转发功能后面再加)
package com.ctb.framework;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 中央控制器,负责接收所有的请求并分别给控制器具体处理
* @author biao
*/
@WebServlet("*.action")
public class ActionDispatchServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
doPost(req, resp);
}
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("dopost ..... ");
}
}
2.Action类定义
Action类定义了每个子控制器需要遵循的行为,使得所有的子控制器都有一个同一的抽象类型,所以我们可以在中央控制器中使用Action类类型来引用所有的子控制器。这样就为用户扩展自定义的子控制器提供了条件。
package com.ctb.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 biao
*
* 2023年6月29日:下午7:08:41
*/
public class Action {
protected void excute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("................");
}
}
3.继承子控制器
package com.ctb.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ctb.framework.Action;
/**
*
* @author biao
*
* 2023年6月29日:下午6:41:01
*/
public class BookAction extends Action{
System.out.println("欢迎来到.....");
}
4.完善中央控制器
为了便于理解,我们可以分步骤的,循序渐进的完善中央控制器:
- 编写简单的请求分发实现功能
- 实现子控制器的功能
- 完善请求参数处理功能
1.请求分发功能
package com.ctb.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.ctb.servlet.BookAction;
/**
* 请求分发功能
* @author biao
*
* 2023年6月29日:下午6:45:13
*/
@WebServlet("*.action")
public class DispathServlet extends HttpServlet{
//用于保存path与action子控制器的映射
public Map<String, Action> actionMap=new HashMap<String, Action>();
@Override
public void init() throws ServletException {
actionMap.put("/book", new BookAction());
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取uri地址
String uri = req.getRequestURI();
//截取
uri=uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
//将uri放到map集合中存储
Action action = actionMap.get(uri);
//获取父类方法
action.excute(req, resp);
}
}
2.action子控制器
在上面的示例中,在中央控制器中直接创建action子控制器
package com.ctb.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 biao
*
* 2023年6月29日:下午7:08:41
*/
public class Action {
protected void excute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取页面传输的参数
String action = req.getParameter("action");
try {
//反射动态方法调用
Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class,HttpServletResponse.class);
method.setAccessible(true);
method.invoke(this, req,resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.请求参数处理功能
package com.ctb.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ctb.framework.Action;
/**
*
* @author biao
*
* 2023年6月29日:下午6:41:01
*/
public class BookAction extends Action{
public void detail(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("欢迎来到查看详情
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)