为了保证BLL与DAL之间相对的独立性,必须采用某种抽象机制,即我们常说的“代理”机制。在这一机制中,BLL将请求发给代理,然后由代理完成对DAL的访问。
SOA与面向对象
面向服务的架构(SOA)并不是一个新概念,它与面向对象(Object-Oriented)概念有很多类似之处。你可能倾向于SOA也可能更看好OO,不过,无论观点如何,了解二者之间的异同都会对你有所帮助。
首先让我们回顾一下面向对象(OO)的概念,图3是一个面向对象模型的典型三层结构。

从图3中可以明显地看出表现层与业务对象的依存关系:客户代码必须与业务层的对象模型交互,这就加强了二者之间的耦合并且需要在层与层之间进行大量的调用。当业务对象驻留在远程机器上时,这种相互之间的频繁调用就会带来很大的问题。同样,表现层对业务对象的操作也降低了层与层之间的独立性,使得对业务层的调用变得很困难。
现在再来看看SOA。图4是一个面向服务的架构(SOA),它所涉及的业务对象与上面所列的相同。

从图4中可以看到,我们引入了一个叫做“服务”的抽象层。表示层不再直接操作业务对象,而是通过服务去访问它们,业务对象驻留在类库里,由服务将它们加载到内存中。此时,因为服务层和业务层都处在在同一流程中,因此对业务对象的操作就变得很容易了。你可以把“服务”看成一个“黑盒子”:它操作业务对象,然后给出结构,从而减少了层与层之间的交互。
对比两种模型,我们不难看出,“全对象”方法存在一定的局限性,与我们所期望的相反,这种局限性也包括“重用”。在“全对象”模型中,层与层之间相互耦合,只有降低耦合度并通过去除不同层中对象之间的直接调用来降低它们相互之间的依赖性后,各模块才能变得更易于重用。
在对象模型中,不同的层在对象的整个生命周期中都是耦合的,即一个逻辑层中的对象在被其上层调用过程中必须是“活的”,而在SOA中并无此要求。在SOA中,内部模块的调用必须支持异步模式或非连接模式。
那么,SOA的出现是否意味着OOP的消亡呢?当然不会!虽然微软公司Indigo的架构设计师Don Box宣称SOA将使面向对象编程方法黯然失色,但事实并非如此!实际上,我们甚至可以把SOA看成是向纯面向对象编程方法的回归。还记得对象理论吗?“对象交换消息并互相调用”,至少在C++、Java和.NET中仍然包含了这些概念,或许SOA将使它们重获新生!
SOA的优点
SOA的出现改变了人们编写应用软件的方式,它要求开发人员将应用设计为服务的集合,并充分考虑现有服务的重用以及如何让新开发出的服务能被其他项目重用。“单独的”、“独立的”、“封装完善的”服务所具有的一个关键好处是可以采用多种不同的方法重新组合它们以形成新的应用。
在应用开发中,采用SOA还会带来很多潜在的优点,其中最主要的包括以下一些:
● 编码灵活性 可基于模块化的低层服务,采用不同组合方式创建高层服务,从而实现重用。此外,由于服务使用者不直接访问服务提供者,因此服务实现方式本身也是灵活的。
● 明确开发人员角色 可以充分发挥开发人员的长处,提高开发效率。例如,熟悉BES的开发人员可以集中精力在重用访问层上;协调层开发人员则无须特别了解BES的实现,而是把精力放在解决高价值的业务问题上。
● 支持多种客户类型 借助精确定义的服务接口和对XML、Web服务标准的支持,SOA可以支持多种客户类型,包括PDA、手机等新型访问渠道。
● 更易维护 服务提供者和服务使用者的松散耦合关系及开放标准的采用使得系统的维护变得更容易。
● 更好的伸缩性 依靠服务设计、开发和部署所采用的架构模型实现伸缩性,服务提供者可以彼此独立地进行调整以满足服务需求。
SOA不仅带来了开发上的好处,它还具有管理上的优点。例如,管理员可以直接管理开发人员所构建的相同的服务,这远胜于以往管理单个应用的方式,通过分析服务间的交互,SOA可以帮助企业了解何时以及为什么业务逻辑被切实执行了,这使管理员或分析师能够有针对性地优化业务流程。
显然,SOA是一种颇具吸引力的架构,因为它具有显著增加应用敏捷性和降低应用总体拥有成本的潜力。
·相关链接·SOA的关键概念
松散耦合
松散耦合是SOA的基本概念,你会在许多场合遇到这个词。在SOA中,松散耦合要实现以下三个主要目标:
● 降低模块之间的耦合度以更好地重用模块;
● 降低平台与基础设施之间的耦合度以获得更好的互操作性;
● 降低服务客户端与该服务特定实现之间的耦合度以获得更好的灵活性。
服务
SOA中最关键的词自然是“服务”,尽管已经有很多人给“服务”下过定义,但要准确地定义它仍然不是件容易的事。在这里,我们给服务下一个简单的定义:“服务是一种可以被调用的模块,它被赋予特定的功能并且有一个定义良好的接口”。
需要注意的是,这里的“服务”并不仅仅是指“Web服务”。事实上,即使不采用Web服务,你也可以实现SOA;相反地,部署Web服务并不意味着你实现了SOA,Web服务仅仅为SOA的实现提供了一种技术手段,用消息队列方式也可以实现SOA。
服务的种类有很多,它们既可以是本地的也可以是远程的。例如,一个服务既可以在Internet上通过SOAP和WSDL产生也可以是数据库、目录等。任何一个服务都是在特定的应用中产生的(很少有人会无缘无故地发布服务),但在设计时必须充分考虑可重用性,使得它也可以用于其他场合。类似地,服务必须被设计成既能被本地调用也能被远程调用。
功能惟一
在SOA中,任何一个服务都必须提供惟一的功能。在图1中,服务A需要认证服务使用者的合法性。

显然,这种方式并不是最恰当的,更好的方式是将认证置于该服务之外,使其本身也成为一个服务——服务B(图2)。

如此一来,服务A就只提供业务功能,对调用者的认证就依赖于提供认证功能的服务B。这种功能细分带来的额外好处是其他服务也可以利用服务B来完成对调用者的认证(图3),从而避免了在每个服务中重复地编写认证代码。记住,在SOA设计中的DRY原则:Don’t Repeat Yourself(千万别重复你自己),在一个系统中,每一种服务都应该是惟一的和定义明确的。

服务接口
在SOA设计中,模块的设计必须从使用者的观点出发。服务是由提供者和使用者间的契约定义的,契约规定了服务使用方法及使用者期望的最终结果,因此,服务的接口必须是简单的。另一方面,服务接口应该与服务的具体实现相分离,一种接口可以被多种实现共享,因为对服务使用者来说,他只关心服务的结果,并不关心它是如何实现的。如此一来,服务提供者就能够很方便地用一种服务替换另一种服务而不会影响与服务使用者之间的联系。