转帖:3层架构?
Posted 炼金士
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了转帖:3层架构?相关的知识,希望对你有一定的参考价值。
以下是转帖,翻译了Rockford Lhotka在04年写的一片文章:
众所周知的,一个典型的应用程序有界面层、业务层和数据层。在我的大部分作品中,我使用的是4层模型:界面、业务、数据访问、数据存储层(UI, business, data access and data storage).在这个案例中,数据存储层确实与传统3层结构中的相同。
原著: http://www.theserverside.net/articles/showarticle.tss?id=FallacyDataLayer
但是,在这里我想将对数据层这个概念提出挑战和质疑。过去的几个月中,在讨论面向服务和分布式面向对象架构中,我日益深信物理数据层(data tier),逻辑数据层(data layer)和 数据存储层(data storage layer)这三个概念之间有根本的缺陷和混淆。
注意,在本文中,我使用layer来描述逻辑概念上的层次,而用tier描述物理上的分隔层次。也就是说,很显然,一个典型的逻辑数据层layer也是物理上的数据层,因为大部分的逻辑数据层都以SQL Server,Oracle或者其他的数据库服务为驱动的。
面向服务的设计给了我们这样一个观点:任何被多于一个组件(或者是说多个客户端)使用的组件都应该是一个服务。服务是超强的软件重用单位,它提供了一个契约式的接口,客户端就可以通过这个接口与服务进行交互。
更重要的一点,一个服务定义了一个信任边界。也就是说,服务保护自己不被非法的客户端使用。这是面向服务的一个定义元素,而且是关键的一点:这个服务可以非常安全的对不同的客户端提供服务,因为它信任所有的客户端(My WebSite注:原文The benefit is that a service can safely service many disparate clients because it trusts none of them 文中有错,应该是all of them.)。服务要确认所有的客户端有相同的行为,而且客户端发送到服务的任何数据都应该基于服务的规则进行有效性验证。
我争论的焦点是传统的数据层是服务的一个理想候选
考虑一个典型应用程序中所有的层:用户或者其他人、表现层的技术、界面逻辑、业务逻辑、数据访问逻辑、数据源。我们可以把这个结构想象成一个堆栈,从用户向下到数据源,应用程序逻辑就像中间的三明治。
但是,我们需要仔细考虑一下我们真正可以控制的是哪些部分,很显然,我们不能控制用户或者其他的(软件)消费者---他们是系统范围影响之外的实体,或者叫做外部实体。
我们可以在很大程度上控制程序的表现形式,就是控制用户界面和业务逻辑层,毕竟,我们把这些代码写在应用程序中。数据访问层也是一样,他只是一些代码用来与数据源进行交互。
现在我们来看看数据源本身,在典型的应用程序场景中,我们是否控制了数据源?呵呵,很多情况下我们回答都是“没有”。在很多情况下,数据源就是数据库,一组关系表,而且现实中,其他的应用程序或者人员几乎经常直接访问那些相同的表,这种情况就不在我们的控制范围之内,所以我们不能保障他们没有使用非法的操作逻辑,而正确的逻辑规则和用法是定义在我们的系统之内的。
这并不是说数据违反了数据库的一致性规则和操作,但是那些规则和操作很少与我们的应用程序规则相匹配,至少不是完全一致。这就意味着在业务逻辑和数据库内建规则之间经常出现不匹配的情况。
说到这里我的观点就是,我们控制不了“光谱”的任何一端,站在应用程序的角度,用户和数据库好像都在我们的控制范围之外。简而言之,我认为数据层是一个外部实体。
微软的Pat Helland谈到服务应该是自制的实体,他包含业务行为和逻辑,另外他也特别注意到每种服务拥有它的数据源。是否就是说,一个给定的服务(程序)有一个专有的控制和访问的数据源?我认同他所讲的内容,但是这很少在实际的公司组织中应用和出现。
而现实情况是,一个服务(程序)与其他的服务共享数据源,其他的服务(程序)也有访问数据源的权限。其他人(管理员、超级用户等等)经常直接访问数据库而绕过了应用程序逻辑。
我认为在一个单独的应用程序中层之间必须互相信任,我已经在我的blog上写过关于信任边界和任何时候如果我们要跨越信任边界,都必须考虑我们有两个独立的应用程序。这是因为,一个应用程序都是在自己的信任边界内定义的。
我意识到我正以一种特殊的方式定义单词应用程序,并且那是有意的。很多关于面向服务的讨论,甚至关于n层架构的讨论都流于语义或者专有名词问题的讨论。我们在此必须定义一套关于讨论的术语。
所以,一个应用程序application是一组包含在一定信任边界内的代码、对象、组件、服务、层(layers or tiers),他们之间互相信任,而不需要重复业务逻辑(验证、计算、操作和授权),因为他们充分信任对方。如果数据在一层验证或者操作过了,那么所有其他层就认为它是正确的。
上边所陈述的观点认为组成应用程序的实体是封装好的,至少在逻辑上是感觉如此。也就是说,外部实体(用户或者其他应用程序)不能直接与代码、对象、组件、服务、层(layers or tiers)直接交互,除非通过应用程序的正式对外接口(用户界面/表现层或者服务接口)。
假如你同意上述的定义和结论,很显然,数据源只有在他作为应用程序专有的数据源时才能成其为一个层。如果数据源不是专有的,那么其他应用程序和用户就可以直接与之交互而不通过我们的应用程序表现层/界面层。在这种情况下(这是通常情况,而非特殊情况),数据源不应该作为应用程序的一个层,因为他存在于信任边界之外,必须作为一个外部实体来考虑(就像对待用户或者其他应用程序)。
从实际的项目角度这意味着什么呢?
呵呵,他意味着我们的应用程序不能信任数据源,但是,更深入的想想,这意味着我们需要基础性的重新思考应用程序(或者服务)的架构。
用户是什么?从应用程序的角度来看,一个用户就是一个数据源或事件触发源。在面向对象的世界里,用户很容易被描述成我们对象模型中的另一个对象,而在面向服务的世界里,用户仅仅被描述成另一个与我们进行交互的服务而已。
事实上,我们可以更进一步的认为ADO.NET, XML, web services, html 和 GUI 都只不过是外部接口技术。我在这里所建议的是没有一个东西可以像表现层/UI层一样,至少没有与数据访问层(或者服务代理层)有实质性的不同,如下所示:
在图中,砖块型的代表应用程序信任边界,我们的业务逻辑和其他任何信任的对象、组件、服务都包含在信任边界盒子之内。信任边界之外,有最终用户、数据源、外部的服务和代理系统,我们的应用程序要与他们交互必须通过信任边界,也就是说他们四个都不被我们的应用程序所信任。
我发现在考虑分布式面向对象的架构中特别具有强迫性。我已经讨论了很多像应用程序和服务可以而且应该用面向对象的方式去创建,但是,如果把我们置身于纯粹面向对象的领域中来看待世界将会怎样?那时用户、数据源、服务和其他任何的不可控制对象有区别吗?根本就没有,每个都仅仅是一个我们需要交互的外部实体,在不同情况下我们通过特殊的接口软件与他们交互,有可能是ADO.NET, Windows 用户界面或者XML解析器。
如果把应用程序作为任何架构的中心,我们能够标准化我们思考外部实体的方式。来自用户的数据、事件或多或少的比来自数据源或者外部服务更有价值。我们的业务逻辑必须基于交互来验证、计算、操作数据而不必管数据的来源。
这就意味着,典型的应用程序的层会更加简单:
l 外部接口
l 内部的业务逻辑。
外部接口可以表现为多种形式,包括:
l 数据访问层(像 ADO.NET)
l 服务代理(例如调用Web Service的类)
l HTML接口(与网络用户交互)
l GUI接口(与Windows用户交互)
在每种情况下,外部接口负责发送和接收数据,还有可能激发和响应事件。更加抽象一点的说,外部接口发送和接收消息,允许与外部和非信任的实体交互。
总之,大部分的数据源都是应用程序专有的,他们被很多应用程序所共享,因此从面向服务的角度来说,数据源可以被认为是一个理想的候选服务提供者。对于其他的共享外部实体也是一样的,就像数据源、用户和其他服务。所以我认为我们需要挑战和怀疑传统的3层架构应用程序模型,从而考虑一种新的架构模型!
以上是关于转帖:3层架构?的主要内容,如果未能解决你的问题,请参考以下文章