自定义MVC框架原理

目录

一、什么是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的核心原则

  1. 核心组件分离: 保持模型、视图和控制器的独立性,每个组件都应该专注于自己的领域。模型负责数据处理和业务逻辑,视图负责展示界面,而控制器负责处理用户输入和协调其他组件。

  2. 清晰的通信接口: 定义清晰的接口和协议,以确保模型、视图和控制器之间的通信和交互是统一和可预测的。这可以减少耦合性,使组件更容易替换和扩展。

  3. 事件驱动: 引入事件驱动的思想可以提高MVC架构的灵活性和响应性。组件之间可以通过事件来进行通信,而不是直接调用方法。这样可以减少依赖关系,使系统更能适应变化。

  4. 分层架构: 根据应用程序的规模和复杂性,可以将MVC架构进一步分层。例如,可以引入服务层或数据访问层来处理特定的功能和访问外部资源,从而实现更好的代码分离和职责划分。

  5. 可测试性和可扩展性: 考虑如何设计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
Vjsp
Cservlet/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("欢迎来到查看详情💕💕💕");
	}
	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("欢迎来到新增💕💕💕");		
	}
	public  void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("欢迎来到主页面💕💕💕");		
	}
}

接下来,我们建一个jsp页面简单测试一下

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<%-- <p>多个servlet进行增删改查</p>
<a href="${pageContext.request.contextPath }/list.do">查询</a>
<a href="${pageContext.request.contextPath }/edit.do">修改</a>
<a href="${pageContext.request.contextPath }/addbook.do">增加</a>
<a href="${pageContext.request.contextPath }/del.do">删除</a>
<a href="${pageContext.request.contextPath }/detail.do">查看详情</a>
<hr>
<p>一个servlet判断参数跳转增删改查方法</p>
<a href="book.action?action=list">查询</a>
<a href="book.action?action=upd">修改</a>
<a href="book.action?action=add">增加</a>
<a href="book.action?action=del">删除</a>
<a href="book.action?action=detail">查看详情</a>
<hr>
<p>反射获取参数调用方法</p>
<a href="book.do?action=list">查询</a>
<a href="book.do?action=upd">修改</a>
<a href="book.do?action=add">增加</a>
<a href="book.do?action=del">删除</a>
<a href="book.do?action=detail">查看详情</a> --%>
<hr>
<p>初步mvc</p>
<a href="book.action?action=list">查询</a>
<a href="book.action?action=upd">修改</a>
<a href="book.action?action=add">增加</a>
<a href="book.action?action=del">删除</a>
<a href="book.action?action=detail">查看详情</a>
</body>
</html>

页面显示:

测试结果:

 这篇文章就到这里结束啦(づ ̄ 3 ̄)づ,拜拜。

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
有了Spring Boot之后,学习MVC还是有必要的。虽然Spring Boot已经集成了Spring MVC,使得开发Web应用变得更加简单和高效,但对于想要深入了解和掌握Spring框架的开发者来说,学习MVC仍然是非常重要的。 首先,学习MVC可以加深对整个Spring框架的理解。Spring MVC是Spring框架中的一个重要模块,它负责处理Web请求和响应,将前端的请求映射到后端的处理逻辑,并返回相应的结果给前端。通过学习MVC的设计原理和工作流程,可以更好地理解Spring的整体架构和核心原理,对于解决实际开发中的问题会更加得心应手。 其次,学习MVC可以提升开发效率。虽然Spring Boot极大地简化了Web应用的开发过程,但有时候我们仍然需要自定义一些特殊的业务逻辑或处理方式。学习MVC可以帮助我们更加灵活地使用Spring Boot的功能,通过自定义控制器、拦截器、视图解析器等组件,实现更加精细化和符合业务需求的开发。 最后,学习MVC可以提高项目的可维护性和扩展性。MVC的分层设计使得业务逻辑、数据访问、界面显示等层次清晰,便于理解和修改。通过学习MVC的设计原则和最佳实践,可以编写出结构清晰、可测试、易于扩展和维护的代码。 综上所述,尽管Spring Boot已经简化了开发Web应用的过程,但学习MVC仍然是非常有价值的。通过学习MVC,可以深入理解Spring框架,并能更加灵活和高效地使用Spring Boot的功能,提高项目的可维护性和扩展性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值