【MVC 1】MVC+EF实体框架—原理解析
导读:在之前,我们学过了三层框架,即:UI、BLL、DAL。我们将页面显示、逻辑处理和数据访问进行分层,避免了一层、两层的混乱。而后,我们又在经典三层的基础上,应用设计模式:外观、抽象工厂+反射,使得经典三层演变为了七层,在一定程度上降低了U层和B层,B层和D层的耦合。
可是,怎样解决D层和数据库之间的耦合?在三层操作中,D层都是直接访问数据库而对数据进行操作,在面向对象的应用中,这似乎显得不太合理,所以,我们应用了EF框架,解决了D层和数据库之间的耦合(这在之前已经说明过了)。在三层中,我们应用了一个抽象工厂+反射和一个接口层,降低了B层和D层之间的耦合,那么由此类推,由面向接口作为切入点,有没有可能再造一个工厂+反射和接口层,从而降低U层和B层之间的耦合呢?
下面,我们来看解决办法:MVC+EF实体框架
一、认识MVC
1.1,定义
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。(摘抄于百度百科)
1.2,理解
模型图:
Model(模型):是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。在这里的Model层,实际上可以过渡到三层中的B层和D层,在MVC中,它将业务逻辑处理和数据访问共同放置于model中,在一定程度上,内部业务和数据访问造成了混乱,耦合度很高。
View(视图):是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。这一层和三层中的UI层,可以等同。
Controller(控制器):是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。很多时候,我们可能容易将这一层类推到三层中的B层,其实,它最多可以等同于七层中的外观层,因为在这里面,它并不涉及到业务逻辑的处理,它只是View和Model之间的桥梁。
1.3,问题
由MVC的理论可以看出,这里至少存在着两个问题:
1,业务逻辑处理和数据存储,被统一放置于Model层,它们之间的高耦合关系怎么处理?
2,Contorller从View提取输入数据,向Model发送,然后返回数据给View层。可以说,controller不管是下至View,或上至Model,都存在了相当可观的耦合。
我们为什么要应用设计模式、框架?我们为什么要抽象出类?我们为什么从不分层、到三层框架,再到EF、MVC,和其他更多的框架。我们都有一个共同的目的:解耦和,实现设计的重用,代码的重用,框架的重用。
二、改造MVC
2.1,Model改造
首先:在MVC中,Model被应用于业务逻辑和数据存储,结合之前所用的三层,那么我们完全可以将Model拆分为B层和D层
其次:为了降低D层和数据库之间的联系,实现面向对象的编程,这里,我们引用EF框架,利用实体映射操作数据,避免和数据库的直接操作,以及为更换数据库提供便利。
2.2,BLL改造
我们可以发现,就算我们增添了一个外观层,我们依然不能减少耦合度,就拿机房收费系统中的例子来说,如果我们要实现一个退卡,那么我们在B层就得有一个是否上机、是否存在卡号的判断,写入退卡表,同时更改学生表中的使用状态。即使,我们用一个外观,也是不能够解决这一问题的。那么,我们试图通过在B层再写一个方法去将这些东西封装,然后再由外观进行实例化这一个封装好的类。可是,这样依旧不能解决实质问题。首先,代码冗余,无法重用?其次,面向接口在哪里?
分析:由退卡可以看出:卡号是否存在,是否在上机,至少这两个判断是在很多地方都要用到的。那么我们是否可以将这些都要用到的方法,作为一个父类进行抽象,通过之类继承的方式,去实现方法的重用。比如说退卡和下机,在第一步,都需要判断是否上机,是否存在卡号。他们不同的在于之后的操作,一个写入退卡记录,一个写入上机记录,所以,它们完全可以继承于同一个类,再而写入自己需要的方法。图像展示:
注意:使用继承,最好不要超过3级。
2.3,DAL改造
由B层的改造,可以得出:我们可以将公共的方法,通过继承的方式,实现重用。那么,在D层中,同样可以。比如说,在实现机房的时候,我们大都用到了一个SQLHelper类,不过,我们是通过实例化的方式。按照分层和面向接口的原理,我们可以将这种基本的方法抽象出来(可以理解为底层),利用继承去达到重用。
附:整体框架图
说明:在B层和D层中间,添加了一个Dbsession,这里也就相当于以前所用过的接口层。
三、思考MVC
在这次的项目中,对于MVC的改造,大都也就是上面所说的了。但是我个人还有些问题:
首先,我们在B和D之间加上了Dbsession这个东西,去提供一个接口调用D层的方法。那么,在Controller和B层之间又该怎么处理?现在的方法是,在配置文件中进行配置,也就相当于以前在做机房时D层所使用过的配置文件,但是,在那时候,D层只需要一个配置文件去配置数据库地址。现在,每一次访问B层,都得在配置文件中进行配置,这样做,功能肯定可以实现,但是,性能方面呢?
思考:可不可以在controller和B层之间,建立一个反射工厂去替换掉配置文件?
其次,利用继承和接口编程,比如说在D层就有了一个类的接口可供调用,为什么还要有一个IDbsession这一层?
四、总结
应用旧知识去学习一个新东西,效率是非常高的。而学习一个新东西,如果能用旧知识去解释,那么理解也会是非常深刻的。没有所谓的框架,只是不停的在解耦和,不停的在实现重用。
可以看出来,在整个的框架中,进行了多次分层,比如说,在BLL的内部就又进行了一次分割。那么这样的做法,是将整个系统的粒度给切分得更加的细致。但是,正如三层一样,不是说东西好,就可以到处拿去用。MVC,不管有没有改造的成分,不管多优良,还是根据实际情况出发,确定要不要使用它。
【MVC 1】MVC+EF实体框架—原理解析的更多相关文章
- 【EF 1】EF实体框架 原理+实例
一.知识回顾 到目前为止,自己学到的链接数据库操作已经经历了几个阶段,分别是:学生信息管理和(第一次)机房收费时的直接连接数据库操作表格,然后是机房个人重构中应用的操作实体,在其中还利用了一个很重要的 ...
- EF实体框架处理实体之间关联关系与EF延迟机制(下)
在数据库中,表与表之间可能存在多种联系,比如,一对多,多对多的关系.当我们使用逻辑外键在数据库建立两张表之间的关系的时候,我们使用EF实体框架 必然也会将这种关系映射到我们的实体关系中来.所以,在我们 ...
- EF实体框架之CodeFirst一
对于SQL Server.MySql.Oracle等这些传统的数据库,基本都是关系型数据库,都是体现实体与实体之间的联系,在以前开发时,可能先根据需求设计数据库,然后在写Model和业务逻辑,对于Mo ...
- EF实体框架之CodeFirst四
在EF实体框架之CodeFirst二中也提到数据库里面一般包括表.列.约束.主外键.级联操作.实体关系(E-R图).存储过程.视图.锁.事务.数据库结构更新等.前面几篇博客把表.存储过程.视图这些算是 ...
- C#.Net EF实体框架入门视频教程
当前位置: 主页 > 编程开发 > C_VC视频教程 > C#.Net EF实体框架入门视频教程 > kingstone金士顿手机内存卡16G仅65元 1.EF实体框架之增加查 ...
- BIM工程信息管理系统-EF实体框架数据操作基类
EF实体框架数据操作基类主要是规范增.改.查.分页.Lambda表达式条件处理,以及异步操作等特性,这样能够尽可能的符合基类这个特殊类的定义,实现功能接口的最大化重用和统一. 1.程序代码 /// & ...
- Config File Settings Of EF——实体框架的配置文件设置
我亦MSDN 原文地址 http://msdn.microsoft.com/en-us/data/jj556606 Entity Framework allows a number of settin ...
- EF实体框架数据操作基类(转)
//----------------------------------------------------------------// Copyright (C) 2013 河南禄恒软件科技有限公司 ...
- EF实体框架数据操作接口(转)
//----------------------------------------------------------------// Copyright (C) 2013 河南禄恒软件科技有限公司 ...
随机推荐
- kafka系列一:单节点伪分布式集群搭建
Kafka集群搭建分为单节点的伪分布式集群和多节点的分布式集群两种,首先来看一下单节点伪分布式集群安装.单节点伪分布式集群是指集群由一台ZooKeeper服务器和一台Kafka broker服务器组成 ...
- Mongodb JAVA API
连接mongodb 1.连接一个mongodb ); 2.连接mongodb集群 MongoClient mongoClient = ), new ServerAddress("localh ...
- Jenkins执行shell脚本启动tomcat失败解决方法
环境:Centos 7 Jenkins版本:2.124 状况:Jenkins会执行服务器某个目录下的Shell, 脚本中功能是复制替换某两个配置文件,然后关闭tomcat,重启Tomcat. 但是,T ...
- jsp中<c:forEach varStatus="status">的属性值问题
c:forEach varStatus属性 current当前这次迭代的(集合中的)项 index当前这次迭代从 0 开始的迭代索引 count当前这次迭代从 1 开始的迭代计数 first用来表明当 ...
- Yii 2.0排序功能的使用
在Yii2.0项目的实际开发中,经常会遇到使用Yii2.0自带的排序功能.下面是排序功能的具体使用方法. 一.设置排序规则 注意引入Sort类,如:use yii\data\Sort; // 设置排序 ...
- vue 中 $set 的使用
在我们使用vue进行开发的过程中,可能会遇到一种情况:当生成vue实例后,当再次给数据赋值时,有时候并不会自动更新到视图上去: <!DOCTYPE html> <html> & ...
- 2.add two number
在初始化的时候:ListNode* result;这样就会报runtime error
- Codeforces Round #271 (Div. 2)-B. Worms
http://codeforces.com/problemset/problem/474/B B. Worms time limit per test 1 second memory limit pe ...
- Dubbo服务的搭建
dubbo框架主要作用是基于RPC的远程调用服务管理,但是注册中心是用的zookeeper,搭建dubbo,首先要安装zookeeper,配置zookeeper... 实现功能如图所示:(存在2个系统 ...
- SpringBoot整合升级Spring Security 报错 【The request was rejected because the URL was not normalized】
前言 最近LZ给项目框架升级, 从Spring1.x升级到Spring2.x, 在这里就不多赘述两个版本之间的区别以及升级的原因. 关于升级过程中踩的坑,在其他博文中会做比较详细的记录,以便给读者参考 ...