这次来讲MVC中***的M。
Model,几乎可以说是网页应用的核心。
之前课程提到过网页应用是由数据库驱动,而在很多场景,数据库 = M ; M = 数据库。
所谓的ORM; object relational mapping。
现在新的网页开发框架,特别是MVC框架,都会提供ORM支持,避免程序员直接写SQL、操作数据库。
传统上,ASP/ php臭名昭著的sql注入问题,便是因为菜鸟程序员直接在程序中根据用户输入拼接数据库造成的;而使用ORM框架,则可以彻底避免这种问题。
ORM有两种风格,一种是 R => O;一种是 O => R 。
====== R => O ======
传统上,程序员也都是先完成数据库设计(甚至是由DBA完成),然后再考虑相应的对象生成,也就是所谓的 R => O。
在这样的场景下,整个软件的框架,还是以数据库为核心,业务的设计思维是以关系型数据库的表结构为基础去考虑的,具体应用实现上,会考虑很多关系型数据库的功能特性,比方说,外键,joining等等,并且,程序员需要直接考虑“数据库设计三范式”,以及冗余字段等面向数据库的优化手段。
并且,程序员也很可能会采用数据库的一些高级特性,如视图、存储过程、甚至触发器等等以方便使用。
O的存在,仅仅是为了方便操作数据库表。
====== O => R ======
这种设计哲学则是相反,程序员做业务分析、实现架构设计的时候,并不过多考虑数据库的特性与限制;程序仅考虑自己的业务对象:编程语言中的对象。
数据库仅仅只是作为一个对象持久层来考虑:
* 程序运行的时候,对象是自动保持在内存中。
* 但在对象状态改变、程序退出的时候,将对象保存进数据库。
* 程序重新启动的时候,则从数据库中获得原先数据,并还原为内存中的对象。
在这样的场景下,数据库是一个可以被替换的存储层,它可以是关系型数据库,也可以是NoSQL,甚至是硬盘文件;所以,即便使用关系型数据库,一般也不会使用其高级功能。
设计哲学的不同直接造成了使用技术的不同。
====== 比较 ======
在ED开发圣经PEAA中,列举了下面三种方案:
1. Trascation Script
也就是直接拼接SQL啦~
2. Table Module
R => O;并且,O非常简单,直接以类似数组的方式读取表数据。
.net中ADO.net的DataTable / DataRow对象便是这种设计的典型实现。
3. Domain Model
O => R,直接设计业务领域(Domain)的对象,然后在考虑对象的持久化方案。
针对上面3中方案,Martin Fowler画了下面这张著名图解:
http://www.hamishgraham.net/page/Work-Habits.aspx/Architecture/Business-Layer
他的结论是:
使用Table Module的方式,永远比直接写SQL简单;在简单的业务场景下,Table Module也会比Domain Model简单,但Table Module的方案复杂度会随着业务复杂化而快速增长。
反之,Domain Model的复杂度跟业务复杂度相比始终保持水平增长;它虽然一开始最复杂,但随着业务复杂度超过一定程度后,它反而会成为最简单的方案。
就我自己的开发经验,基本与Fowler的描述吻合;但随着ORM技术的成熟,Domain Model,未必如他在图中画的那样,一开始就有那么高的复杂度。
关键是看程序员是否习惯于关系型数据库的实现方案,如果是,那么,切换去Domain Model,确实会比较麻烦,各种不适应。
但如果是一个没有关系型数据库经验的程序员,或者说,没有强制使用SQL思维习惯的程序员,使用Domain Model,也可以是很自然的方案。
下一课,讲继续详细说明Domain Model。
作业:
1. ED开发圣经PEAA究竟是哪本书?
2. 数据库三范式是什么?
3. 关于Domain Model,什么是充血模型?什么是贫血模型?
51CTO系列: