虽然我还太年轻,没有从事过早期批处理系统时期的任何工作,但我感觉当时人们不会太关注层次的概念,只要编写操作某些文件(ISAM、VSAM等)格式的程序,这就是当时的应用。它不需要层次。
20世纪90年代,随着 客户 / 服务器 系统的兴起,层次的概念变得更明显。这样的系统是一种两个层次的系统:客户持有用户界面和其他应用代码,服务器通常是关系型数据库。常见的客户端工具是VB、Powerbuilder和Delphi。这些工具使得构建数据密集型应用变得非常容易。因为它们的用户界面控件通常都是SQL感知的。因此,可以通过将控件拖拽到“设计区域”来建立界面,然后再使用属性表单把控件连接到后台数据库。
如果应用仅仅包括关系数据的显示和简单修改,那么这种客户/服务器系统的工作方式非常合适。问题来自领域逻辑:业务规则、验证、计算等。通常,人们会把它们写在客户端,但是这样很笨拙,并且往往把领域逻辑直接嵌入用户界面。随着领域逻辑的不断复杂化,这些代码将越来越难处理。而且,这样做很容易产生冗余代码,这意味着简单的变化都会导致要在很多界面中寻找相似代码。
另外一种方法是把这些领域逻辑作为存储过程放在数据库中。但是,存储过程只提供有限的结构化机制,这将再次导致笨拙的代码。而且,很多人喜欢关系型数据库的原因之一是SQL是一个标准,允许他们更换数据库厂商。尽管真正更换数据库厂商的用户寥寥无几,但还是有很多人希望拥有在不太高的移植成本下更换供应商的选择。由于存储过程都是数据库厂商私有的,因此这种选择权被剥夺了。
在客户/服务器方式逐渐大众化的同时,面向对象的世界也在崛起。对象社群为领域逻辑的问题找到了答案:转到三层系统。在这种方式下,有一个表示层用于UI,一个领域层用于领域逻辑,还有一个数据源。这种方式使你可以将复杂的领域逻辑从界面中抽取出来,单独放到中间层,用对象加以建模和组织。
尽管有这些优势,但一开始面向对象的进展并不大。当时的实际情况是:大多数系统并不特别复杂,或者至少在构建之初没有那么复杂。因此,当系统比较简单时,客户/服务器工具还是很有吸引力的。客户/服务器工具在三层配置中也很难使用,甚至不可能使用。
我认为真正巨大的冲击来自Web的兴起。人们忽然想在Web浏览器上部署这些客户/服务器应用。然而,如果所有的领域逻辑都埋在一个富客户中,则所有这些都必须针对Web界面重写。对于设计良好的三层系统来说,只需要增加一个新的表示层,就可以了。另外,通过Java,我们看到了一门面向对象语言毫无掩饰地成为主流。用于构建Web页面的工具对SQL的绑定也没有那么紧密了,这也使得它们比较容易适应三层结构。
当人们讨论分层时,常常不容易区分layer和tier。这两个词汇经常被用作同义词,但是很多人还是认为tier意味着物理上的分离。客户/服务器系统常常被称为“two-tier system”,其分离是物理上的分离:客户是一台台式机,而服务器是一台服务器。我使用layer,旨在强调无须把不同的层次放在不同的计算机上运行。独立出来的领域逻辑层既可以运行在台式计算机上,也可以运行在数据库服务器上。在这种情形下,有两个节点,但是有三层。如果数据库也在本地,还可以在一台笔记本电脑上运行所有三层,当然,仍旧存在三个截然不同的层。