MVC架构详细介绍与分析-程序员宅基地

技术标签: spring  架构  java  javaweb  mvc  

MVC

   Mvc概念:M:model(模型),V:view(视图),C:Controller(控制器)
在这里插入图片描述

MVC控制流程图
   Mvc的处理过程是由控制器是接收业务请求,并决定调用那个模型来进行处理,然后模型业务逻辑来处理用户的请求并返回数据,最后控制器用相应的视图格式化模型返回的数据,并通过视图层呈现给用户。

层次概念

视图层:用于做数据的展示以及与用户进行交互的一个界面
控制层:能够接收客户端的请求,具体的业务功能还是需要模型组件来完成。
模型层:负责处理业务逻辑以及数据库的交互,承载数据。模型分为多种,有简单的pojo/vo(value object),有业务模型组件,以及数据访问层组件。

模型层类别:
1)pojo/vo:值对象:一个fruit类就是值对象,可以获取相应的属性数据。
在这里插入图片描述

2)DAO:数据访问对象:连接数据库并操作相应数据库表单的DAO类

在这里插入图片描述

3)BO: 业务对象:业务对象调用相应的数据对象进行一系列操作。
在这里插入图片描述

区分业务对象以及数据访问对象:
1)DAO中的方法都是单精度方法或细粒度的方法,一个方法只考虑一个操作,比如添加到数据库就是insert,无需考虑其他操作的影响。
2)BO中的方法属于业务方法,实际的业务是比较复杂的,因此业务方法粒度是比较粗的。service层的业务实现,具体要调用已经定义的dao层接口,封装service层业务逻辑有利于通用的业务逻辑的独立性和重复利用性。程序显得非常简洁。
   例如账户注册这个功能属于业务功能,因此注册这个方法属于业务方法。
那么这个业务方法就包含了许多DAO方法,也就是说注册这个业务功能需要通过多个DAO方法的组合进行调用,从而完成注册功能的实现。
注册:
1、检查用户名是否被注册-DAO中的select操作
2、向用户表新增一条新用户记录-DAO中的insert操作
3、向用户表新增一条新用户记录-DAO中的insert操作
4、向系统消息表新增一条新用户记录-DAO中的insert操作
5、向系统日志表新增一条新用户记录-DAO中的insert操作
6、。。。
简单的说DAO层是跟数据库打交道的,service层是处理一些业务流程(不仅仅包括DAO调用操作)。

MVC构建的优点

  能够将各个层次强制性分开,这样分开之后就会减少层与层之间的依赖,这样就能最大化的重用代码了。例如MVC层的话多个视图就能共享一个模型,控制器也可以连接不同的模型和视图来完成用户的需求,三个部件相互独立这种设计思想能构造好的松耦合构建。

在水果项目系统中添加实现业务层的概念

  在原来优化后的水果系统中用户发送请求的处理流程如下图所示:
在这里插入图片描述
  用户中央控制器接收请求后直接向控制层发出命令,由控制层访问model进行一系列的DAO方法调用获取数据,最后view渲染页面。
  当日积月累的使用MVC模式开发之后,会逐渐感受到层与层之间的粘连以及模棱两可的地方存在,这就是service层出现的重要原因。业务逻辑粘连了C层以及M层,因此需要将业务逻辑解耦出来,成为独立的Service层。
  假设现在你做这个功能会用到user表和权限表,那么你前台的页面访问action,action再去调用用户模块service,用户模块service判断你是操作user表还是权限表,如果你操作的是user表则service的实现类就去调用userDAO。如果是操作的是权限表则调用权限的DAO。也就是说DAO一定是和数据库的每张表一一对应,而service则不是。


没有service层会产生的问题:
   只能在控制层直接实现业务逻辑导致多个控制器无法共享通用的业务逻辑,如果业务逻辑需要升级,则需要直接在源代码上修改兼容,会导致控制器代码不断膨胀复杂。

service层的作用:
 service是业务层,是使用一个或者多个模型执行操作的方法。
      1:封装一些通用的业务逻辑。
      2:与数据层交互。
     3:其他请求:如获取远程服务数据。

因此需构建一个业务模型来进行模型的调用,这样控制器能够更专注于模型构建的调用以及视图的处理。

package com.ck.fruit.biz.impl;
import com.ck.dao.FruitDAO;
import com.ck.fruit.biz.FruitService;
import com.ck.fruit.pojo.Fruit;
import java.util.List;
public class FruitServiceImpl implements FruitService {
    
    FruitDAO fruitDAO=null;
    @Override
    public List<Fruit> getFruitList(String keyword, Integer pageNo) {
    
        return  fruitDAO.getFruitList(keyword,pageNo);
    }
    @Override
    public void addFruit(Fruit fruit) {
    
        fruitDAO.addFruit(fruit);
    }
    @Override
    public Fruit getFruitById(Integer fid) {
    
        return fruitDAO.getFruitByFid(fid);
    }
    @Override
    public void delFruit(Integer fid) {
    
        fruitDAO.deleteFruit(fid);
    }
    @Override
    public Integer getPageCount(String keyword) {
    
        Integer fruitCount=fruitDAO.countNum(keyword);
        Integer pageCount=(fruitCount+5-1)/5;
        return pageCount;
    }
    @Override
    public void updateFruit(Fruit fruit) {
    
        fruitDAO.updateFruit(fruit);
    }
}

构建上述模型之后在控制器上进行业务调用即可,无需再直接再调用fruitDAO中的方法。
在这里插入图片描述
在这里插入图片描述
  Service层是建立在DAO层之上的,建立了DAO层后才可以建立Service层,而Service层又是在Controller层之下的,因而Service层应该既调用DAO层的接口,又要提供接口给Controller层的类来进行调用,它刚好处于一个中间层的位置。每个模型都有一个Service接口,每个接口分别封装各自的业务处理方法。

IOC

  采用MVC综合设计模式,MVC本身不属于设计模式的一种,它描述的是一种结构,最终目的达到解耦,解耦说的意思是你更改某一层代码,不会影响我其他层代码,如果你会像spring这样的框架,你会了解面向接口编程,表示层调用控制层,控制层调用业务层,业务层调用数据访问层。初期也许都是new对象去调用下一层,比如你在业务层new一个DAO类的对象,调用DAO类方法访问数据库,这样写是不对的,因为在业务层中是不应该含有具体对象,最多只能有引用,如果有具体对象存在,就耦合了。因此在层与层之间实现解耦很有必要,IOC就能实现此需求。

概念理解

  1. 耦合/依赖
    依赖指的是某某某离不开某某某
    在软件系统中,层与层之间是存在依赖的。我们也称之为耦合。
    我们系统架构或者是设计的一个原则是: 高内聚低耦合。
    层内部的组成应该是高度聚合的,而层与层之间的关系应该是低耦合的,最理想的情况0耦合(就是没有耦合)
  2. IOC - 控制反转 / DI - 依赖注入
    控制反转:
    1)在之前项目中的ControllerServlet中,我们创建了service对象,FruitService fruitservice=new FruitServiceImpl();
    如果出现在Servlet的某个方法中,那么这个fruitservice的作用域(生命周期)就是方法级别。
    如果出现在servlet类中,也就是fruitService是一个成员变量,那么这个fruitservice的作用域就是这个servlet实例级别。
    2)之后我们在applicationContext.xml中定义了这个fruitService,然后通过解析XML,产生fruitService实例,存放在beanMap中,这个beanMap在beanFactory类中产生其他类的实例。因此,我们转移(改变)了之前的service实例,DAO实例等等他们的生命周期。控制权从程序员转移到了BeanFactory。这个现象称为控制反转。

    依赖注入:
    1.之前我们在控制层出现代码:FruitService fruitService=new FruitServiceImpl(),那么,控制层与service层存在耦合.
    2.之后,我们将代码修改成FruitService fruitService=null,然后在配置文件中配置:
<bean id="fruit" class="com.ck.fruit.controllers.FruitController">
    <property name="fruitService" ref="fruitService"/>
</bean>

这样就可以通过配置中的属性找到类所需要的依赖并进行实例化,这就是注入依赖。

在水果项目系统中添加控制反转与依赖注入

  1.在原先的项目中在控制器以及service层中均存在实例化其它层的类再进行调用,这样层与层之间就存在耦合依赖的情况,因此需要对当前结构进行改进。
在这里插入图片描述在这里插入图片描述

  2.将需要的类先赋值为null
在这里插入图片描述在这里插入图片描述

   3.建立一个Beanfactory接口并创建其实现类用来构建一个MAP集合存放xml配置文件中存放的类
xml配置文件,各个bean节点对应各个类,bean中的property节点表示该bean代表的类需要依赖的类,用于后续注入依赖使用。
在这里插入图片描述

  ClassPathXmlApplicationContext类实现beanFactory接口,将xml配置文件中的类全部通过反射映射入相应集合中:
在这里插入图片描述

   将xml中所有的类注入集合后就要开始组装bean之间的依赖关系,通过获取bean下的property子节点,来从集合中获取相应的类实例,然后通过反射技术将相应的类中的属性赋值,注入依赖。
在这里插入图片描述
最终实现水果系统:

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ccjjjjdff/article/details/129497607

智能推荐

Docker搭建MySQL集群环境_容器版mysql集群搭建-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏4次。文章目录安装Docker使Docker容器和Windows10建立局域网连接Docker创建一个局域网在Windows10中将这个子网添加到路由表中简单Mysql持久化预先准备启动mysql搭建MySQL集群预习准备修改配置文件修改my.cnf修改mysql-cluster.cnf启动5个节点参考资料安装Docker由于我用的是Windows10,所以我打开了Hyper-V,然后在Dcoker..._容器版mysql集群搭建

Niagara内容示例 4.3 Mesh Orientation vs. Rotational Force_ue5 的niagara 的drag是什么?-程序员宅基地

文章浏览阅读2.1k次,点赞3次,收藏6次。粒子效果有三竖列的粒子,都在绕某个轴进行旋转。根据下面的文本提示来看,应该是每堆粒子的旋转操作的赋予方式不同,分别是直接操作网格体朝向(Mesh Orientation),操作旋转的速度(Rotational Velocity),操作发起旋转的力(Rotational Force)。(理科生可能会比较好懂,其实就是分别操作位置,速度以及加速度,如果你脑中有公式的话,其实这三者做的是同一件事,。)Niagara蓝图部分蓝图中包含了三个发射器(对应三种模式),并配文做出相应的解释。左上角是操作Mesh朝._ue5 的niagara 的drag是什么?

机器学习复习——pLSA、LDA_plsa机器学习-程序员宅基地

文章浏览阅读563次。pLSA:pLSA由LSA发展过来,而早期LSA的实现主要是通过SVD分解。pLSA的模型图如下:公式中的意义如下:具体可以参考2010龙星计划:机器学习中对应的主题模型那一讲 LDA:主题模型,概率图如下:和pLSA不同的是LDA中假设了很多先验分布,且一般参数的先验分布都假设为Dirichlet_plsa机器学习

java 实现文件下载功能(浏览器提示保存位置)_java文件下载时如何可以弹出下载框选择路径-程序员宅基地

文章浏览阅读2.5k次。@RequestMapping(params = "down") public void down(HttpServletResponse response,@RequestParam("file") String file) { try { String filePath = "E:\\saveWenJian\\"+file; InputStream is = new FileInputStream(filePath); response.reset(); // 必要地清除res._java文件下载时如何可以弹出下载框选择路径

java中实现类似C#的TrimEnd函数_java trimend-程序员宅基地

文章浏览阅读2.6k次,点赞4次,收藏2次。话不多说,直接上代码/* * 删除末尾字符串 */public static String trimend(String inStr, String suffix) { while(inStr.endsWith(suffix)){ inStr = inStr.substring(0,inStr.length()-suffix.length()); } return inStr;}public static void main(String[] ar._java trimend

Java 中HashMap 详解_java hashmap-程序员宅基地

文章浏览阅读2.2w次,点赞13次,收藏53次。举一个简单的例子,假设我们在目前的平台有键值对 key1-value1,计算出key1的hash为1, 计算后存在table数组中下标为1的地方,假设table被序列化了,并传输到了另外的平台,并反序列化为了原来的HashMap,key1-value1仍然存在下标1的位置,当在这个平台运行get("key1")的时候,可能计算出key1的hash为2,就有可能到下标为2的地方去找该元素,这样就出错了。创建新的Node数组,将原来数组中的元素重新映射到新的数组中。2. 数组的默认长度是16。_java hashmap

随便推点

MATLAB解决梯子问题,MATLAB常见问题解决方法-程序员宅基地

文章浏览阅读581次。刚看到的,相信对大家有用。谢谢作者!故障一:matlab一打开随即自动关闭解决方法: 这是CPU和默认设置不一样造成的。假设你的CPU不是P4,而是AMD的ATHLON那么修改的方法就是:首先请确认你的MATLAB的文件夹中有如下文件:atlas_Athlon.dll(AMD系列的请用这个,其他的CPU也有相应的问题件,就在MATLAB文件夹下),这些是对应处理器的数值运算优化文件。然后请按如下步...

【git问题处理】SSL routines:ssl3_get_record:wrong version number问题解决小记-程序员宅基地

文章浏览阅读1.4k次。本文整理了git clone时遇到SSL routines:ssl3_get_record:wrong version number问题的解决方法。_ssl routines:ssl3_get_record:wrong version number

PathVariable注解的使用,必须技巧_getmapper注解一定要设置pathvariable才能取到值吗-程序员宅基地

文章浏览阅读51次。PathVariable注解一般都是,将Mapping中的路径值赋值给方法形参如下。假设:@GetMapping("/{id}") 中id为 8。而如果没有PathVariable注解输出结果将是null。所以最后输出结果为 8。即形参id的值也是8。_getmapper注解一定要设置pathvariable才能取到值吗

优雅的数据结构---并查集_数据结构菊花图-程序员宅基地

文章浏览阅读64次。数据结构,算法,并查集_数据结构菊花图

/usr/include/glib-2.0/glib/gtypes.h:32:10: fatal error: glibconfig.h: No such file or directory-程序员宅基地

文章浏览阅读3.2k次,点赞2次,收藏4次。  具体错误:/usr/include/glib-2.0/glib/gtypes.h:32:10: fatal error: glibconfig.h: No such file or directory #include <glibconfig.h>这个文件是有的:cd /usrfind -name glibconfig.h./lib/sw_64-linux-gnu/glib-2.0/include/glibconfig.h解决办法:在编译选项中,加上-I/u_/usr/include/glib-2.0/glib/gtypes.h:32:10: fatal error: glibconfig.h: no suc

echarts柱状图刻度_echarts中柱状图的刻度问题-程序员宅基地

文章浏览阅读2.1k次。想实现一个柱状图,表示范围的数值以下是option的代码option = {color: ['#3398DB'],tooltip : {trigger: 'axis',axisPointer : { // 坐标轴指示器,坐标轴触发有效type : 'shadow' // 默认为直线,可选为:'line' | 'shadow'}},grid: {left: '3%..._echarts柱状图 控制刻度

推荐文章

热门文章

相关标签