1、三层构架和 MVC 意思一样么?
Java WEB 开发中,服务端通常分为表示层、业务层、持久层,这就是所谓的三层架构:
1、表示层负责接收用户请求、转发请求、生成数据的视图等;
2、业务层负责组织业务逻辑;
3、持久层负责持久化业务对象;
这三个分层,每一层都有不同的模式,即架构模式,如下图:
最开始学 Java WEB 的时候,认为 MVC 就是 Java 里的三层架构,后来又认识到这样的想法不对,升华到认为 MVC 是表示层的架构模式,表示层最常用的架构模式就是MVC。
这个话题其实十年前,Java 社区都已经讨论烂了,真是悲剧,因为后来我还一直认为:MVC 意思是模型层、视图层、控制器层,其实哪里来的这么多层?是不是还要来个Service 层、DAO 层、DTO 层?
这是不正确的认识……
MVC 就是 M——模型、V——视图、C——控制器,而层的英文是 tier(物理上)、或者 layer(逻辑上)。即,层有类似计算机网络那种从上到下的递进关系,而模型、视图、控制器没有从上到下的明确关系。
MVC 并非谁创造的理论,它只是被赋予一个世界通用的名字,任何有经验,有追求的程序员即使完全不知道 MVC 这个东西,也都会走向 MVC。
故我的认知最后升华为:MVC 是模型,视图,控制器,和三层架构不是一个东西。它们更不是什么视图层,模型层,控制器层,没有这个说法,但凡这么说的,要么就是习惯了这么说,要么就是理解错误。
2、MVC 是表示层的架构模式
Java WEB 的三层架构是一个设计上的分层思想,三层架构设计中的每层都有自己的架构模式,架构模式就是每层的套路,类似传统武术里的套路,每一层都有自己的套路,这个套路就是所谓的架构模式。
表示层最常用的套路就是 MVC ,它不是软件设计模式,这是不同的概念,硬要扯上关系,只能说 MVC——这个企业级开发架构中的表示层常用的架构模式包含了多个软件设计模式的思想。
比如,MVC 架构模式是多种设计模式的复合,也可以说是复合设计模式的体现:
1、Model 和 Controller 之间是策略模式 ,表示对同样的数据可以有不同的处理策略(算法),参考:接口的常用用法都有什么?策略设计模式复习总结
2、Model 和 View 之间是观察者模式,View 表示观察者, Model 是主题,View 订阅了主题(Model)……参考:发布订阅/回调模型的核心技术——观察者模式复习总结
MVC 在实际环境中有很多的变体和改进,只要体会其中思想,无需严格跟概念相同,比如常见的有经典 MVC 和 Web 开发的 MVC 架构模式。
登录用户也就是浏览器客户端(很多时候以计算机的角度看程序更容易理解程序)是和控制器——Controller 交互的,而客户端看到的是 View ,它看不到 model。
客户端里;输入用户名,密码 》发送http请求 》触发 Controller 调用 Model 的数据校验接口,Model 校验不符合,触发 Controller 选择登录失败的 View 返回给客户端,用户就看到一个登录失败的提示,之后客户端里输入正确的密码,重复之前的操作,如 model 校验 success,则触发 Controller 去做对应策略的选择,再调用 model 的登录接口来请求登录(策略设计模式),model 和数据存储系统交互,完毕之后触发 controller 更新 view(观察者设计模式)……用户就看到登录成功的提示了。
3、业务层的架构模式
业务层的架构模式有事务脚本模式、领域模型模式等等,企业应用中最关键的显然是业务层。
事务脚本模式是最简单,最容易掌握的,如果开发团队面向对象设计能力一般,而且业务逻辑相对简单,业务层一般都会采用事务脚本模式,因为简单
如果业务逻辑复杂,用事务脚本模式就很不明智了,简单点讲,就是违背了单一职责设计原则,Service 类成为万能的上帝,承担了太多职责……
3.1、事务脚本模式
事务这里代表表示层的一个请求,所谓脚本就是一个方法,所谓事务脚本就是将一次请求封装为一个方法,所谓事务脚本模式,就是将业务层的对象分为三类,其中:
1、Service 类封装业务流程,或者说是纯粹的界面上的业务流程
2、DAO 类只负责对数据的操作,也就是封装对持久层的访问
3、DTO(Student)类封装业务的实体对象,负责业务层内数据的传输流动
各个对象之间的关系,按照下图的方式组织起来——简单的学生管理业务层UML类图:
service类:包含一个 service 接口和对应的 service 接口的实现类,dao 类似,而 dao 和 service 是一种聚合关系,service 类聚合了 dao 类。
对于聚合:聚合是关联关系的一种特例,他体现的是整体与部分、拥有的关系,即 has-a 的关系,此时整体与部分之间是可分离的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享;
比如计算机与cpu、公司与员工的关系等,表现在代码层面,和关联关系是一致的,只能从语义级别来区分;
DTO类:在 dao 和 service 中都有关系,属于依赖关系。即:dao,service 依赖 DTO 类来传输数据对象
依赖:是类 A 使用到了另一个类 B,而这种使用关系是具有偶然性的、临时性的、非常弱的,但是 B 类的变化会影响到 A;
比如某人要过河,需要借用一条船,此时人与船之间的关系就是依赖,表现在代码层面为:类B(DTO)作为参数被类A(dao,service)在某个 method 使用,这就是所谓业务逻辑的组织方式
3.2、为什么要用 Service 接口和 DAO 接口?
还得回到最基本的面向对象设计原则上去,有三条与此相关:
1、开闭原则
2、依赖倒转原则
3、里氏替换原则
依赖倒转原则:高层不依赖于低层,二者都依赖于抽象,也就是面向接口编程。用 Service 接口是让表示层不依赖于业务层的具体实现。用 DAO 接口是让业务层不依赖于持久层的具体实现
有了这两个接口,Spring IOC 容器才能发挥作用
举个例子,用 DAO 接口,那么持久层用 Hibernate,还是用 mybatis,还是 JDBC,随时可以替换,不用修改业务层的 Service 类的代码。dao,service 使用接口的意义就在此。
4、持久层的架构模式
持久层的架构模式有入口模式(MyBatis、JDBC 是入口模式的典型实践)、数据映射器模式(Hibernate 是数据映射器架构模式的典型实践)等等。篇幅有限,不多说。
一般来说,框架 > 架构模式 > 设计模式 > 设计原则
打个比方:
1、Hibernate 是一个持久层框架,是数据映射器架构模式的具体实现,实现时用到了工厂模式等软件设计模式,体现了依赖倒转、开闭、里氏替换等等设计原则。
2、SpringMVC 是一个表示层 MVC 架构模式的实现框架,是 MVC 架构模式的一种实现,实现时用到……设计模式等,体现了……设计原则,诸如此类。
前面总结了那么多,貌似有些跑。
欢迎关注
dashuai的博客是终身学习践行者,大厂程序员,且专注于工作经验、学习笔记的分享和日常吐槽,包括但不限于互联网行业,附带分享一些PDF电子书,资料,帮忙内推,欢迎拍砖!