导读:在之前,我们学过了三层框架,即: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,不管有没有改造的成分,不管多优良,还是根据实际情况出发,确定要不要使用它。