嗯,MVC
说起MVC,码农们再熟悉不过了。这是一个老生常谈的问题。无论是技术面试、技术讨论、还是平时做Web应用、移动应用,都避不开它:
Model:模型,用来处理应用程序的数据逻辑.
View:视图,用来展示数据效果。
Controller:控制器,用来响应来自View的请求,作为代理来处理请求,并把结果返回给View。
MVC框架存在的意义
现在可以用做Web开发的每种语言里都提供了很多MVC框架,像Java中的Struts2、Spring MVC,PHP中的Yii、ThinkPHP、YAF、Phalcon等等。大大提高了Web开发的效率,增强了Web开发的规范。但是,框架的存在并不仅仅是用来提高开发效率的。反过来说,想要提高开发效率,也不应该仅仅依赖于框架本身,更应该依赖使用框架的人对软件复用的理解和应用。
框架也是基于软件复用这一目的而产生的。
C 和 M 到底该扮演什么角色
业务逻辑在哪里
多个功能的集合组成了一个Web/移动应用,我们的业务逻辑就分散在一个个功能上面。Controller里有业务逻辑吗?有。比如,我们需要在Controller里检查参数的正确与否,这就是业务逻辑的一部分;我们需要在参数正确的情况下,做进一步的数据读取和处理,这也是业务逻辑的一部分。Model中有业务逻辑吗?也有。比如,我们需要根据Controller的调用,去存储、读取数据。
既然业务逻辑在Controller和Model中都存在,那么它们存在的意义有什么区别呢?或者说各自的侧重点是什么呢?
Controller和Model不是平行的,是一上一下的层级关系,可以把它想象成上下级的关系。它们各自承担的业务逻辑的粒度大小是有区别的。Controller承担粗粒度的事情,Model则承担细粒度的事情。
C 该做什么,不该做什么
Controller应该扮演一个协调者、管理者的角色:
- 协调View和Model的关系:当View的请求到来时,需要负责从开始接到请求到最终返回结果的一系列步骤。
- 负责对Model的调用:Controller是个管理者,它知道一个请求到来时,需要由哪个或哪几个Model分别来做,以及做事情的顺序。
- Controller不做具体的事情,涉及到具体的事情时,都会交给下属去做,也就是交由Model来做。
M 该做什么,不该做什么
Model应该扮演的两个角色:
- 负责一个相对集中的功能下面的具体的业务逻辑。
- 负责对数据的存取。
对于Controller来说,Model里的两个角色没有区分,是透明的。但对于Model来说,这两种角色是有差异的。首先,业务逻辑和数据的存取是相对独立的,并且二者是一上一下的层级关系。其次,业务逻辑与数据的存取是相互交叉的,即不同的业务逻辑可以共用同一个数据存取服务。所以体现在框架的使用上面,应该在Model层下划分出业务逻辑层(Logic Layer)和数据访问层(Data Access Layer)。
工作中遇到的一些例子
Java框架里,对设计模式的依赖度较高,设计时,基本都会把Model层划分成业务逻辑层(Logic Layer)和数据访问层(Data Access Layer)。但在PHP里,有些框架只会给出Model层,或者在代码体现上只有Model目录。这时候,开发者往往会把业务逻辑写在Controller里面,把Model层仅仅用作数据存取,即Data Access Layer。结果就是很多业务逻辑代码在不同的Controller里重复出现,或者为了复用而被扔到基类里去,没有达到使用框架的最终目的。
可能有人会担心框架的效率问题。本来框架已经耗费了一定的时间,如果在Controller和Model的数据读取层中间再加一层业务逻辑层,会不会导致性能问题呢?其实这个问题,网上会有很多讨论,性能问题不应该在框架这一层来展开讨论,因为性能问题的最终原因应该在架构层面。框架自身带来的性能消耗是整个请求耗时中很小的一部分。框架带来的便利性(如果框架没有大而全而且复杂难以使用的话)远大于它带来的性能消耗的影响。关于框架性能消耗的细节,可以去网上看各个框架的Benchmark。
总之
MVC框架不是目的,目的是如何更好的实现软件复用,以节省开发成本、维护成本。