深入SOA的一些细节

进来博客堂关于SOA的文章不少,呵呵,看来SOA进入大家的实际项目可能是指日可待啊。

 

因为SOA绝不是一种标准,而且也是刚刚发展推广开的一种架构,所以在网上对于一些细节(也许下面罗列的已经算不得是细节了)的地方, 各有各的看法,各有各的理由。

 

一、Service Façade公开Entity还是公开Argument

 

比如,应该是这样:

CustomerService.AddCustomer ( CustomerInfo customer )

还是:

CustomerService.AddCustomer ( String name, String zipcode, Int32 level )

 

首先看张图,http://bbs.dotnettools.org/upload/1308-Architecture%20Design.jpg(此图取自.NET Tools评测网论坛redmoon的一个介绍产品架构的帖子,同时推荐大家可以去论坛看看redmoonccboyjjxJGTM2004关于SOA的精彩发言)。

 

从这张图可以看到,由Typed DataSet实现的Entity横跨了整个系统(也就是在整个系统间传递了,就像是我以前的那篇文章上所说的,DTO在模块间流动),甚至通过Service的边界传递给了Service Customer。如果你的整个系统都是.NET,并且能够把包含了EntityAssembly部署到系统的各个模块(所以建议将系统中用到的所有Entity单独放在一个项目中,并被其他所有的项目引用),这样做绝对是简洁、明了、高效的选择。

 

但很多人会不同意这样(我估计JGTM2004会不同意,基于他发出的帖子所表达的观点来判断)。因为很多人认为作为一个独立的、自维护的、解耦的Service来说,你公开一个你自己才明白的Entity,别人(就是Service消费者了)根本不懂,何况说不定一个Java系统以后也想要调用这个Service呢。所以,很多人都说,“Services expose Schema and Contract, not Class and Type”,就是说,ServiceService之间要传递中立的,有良好Schema定义的Message

 

再反过来说:好像是在今年二月份的《程序员》杂志上,有一篇文章讲到一个失败的案例,其中有一点就是各个模块间的调用都是通过参数,而不是Entity,结果后期客户增加了一个字段信息,所牵涉的要更改的地方非常之多(因为模块接口都要改),所以那篇文章的作者认为,为了能够在对象结构变化的情况下,接口相对固定,模块接口参数一定要是一个Class

 

二、Entity自己维护相互的Relations吗?

 

比如,CustomerInfo这个纯数据Entity是否应该包含OrderInfo的集合(提供一个Orders属性来公开),同时OrderInfo包含一个CustomerInfo的引用(提供一个Customer属性)?

 

包含?那么当Service CustomerService请求一个CustomerInfo时,其对应的OrderInfo集合也被自动同时从数据库中取出来,并打包到CustomerInfo一起传回来?还是用类似Lazy-Loading之类的方法先不取回来?一起传回来在某些场合是明显的浪费。哇,好像真是头疼的选择。

 

Lazy-LoadingSOA中应用可不是件简单的事。比如客户端请求一个OrderInfo,然后引用其Customer属性,ServiceLazy-Loading来载入正确的CustomerInfo对象并返回,然后客户端再引用这个CustomerInfo对象的Orders属性,这时Service应该能够正确判断出哪些Order已经被载入了而可以从缓存中直接取,哪些没有载入而需要从数据库中取…ORM可能是个不错的选择。

 

如果干脆让Entity不自己维护其Relations关系,那么客户端就要像这样调用Service了:

 

CustomerInfo customer = CustomerService.GetCustomer( “kaneboy” );

// …

OrderInfoCollection orders = CustomerService.GetOrders ( customer.Name );

// …

CustomerService.UpdateCustomer( customer );

CustomerService.UpdateOrder( orders[0] );

 

重复向Service请求,由知道其关系的Service来处理。而且客户端代码可麻烦了,因为CustomerInfoOrderInfo“实际上”不知道他们之间有什么关系,在需要根据其Relations进行某些处理时,就需要代码来手工处理了。

 

好像文章没有做出一个结论,因为本身就无法做一个“绝对”正确的选择。我个人更喜欢Service公开EntityEntity自己维护其Relations,但是,“Do right things in right place”,呵呵。

附注:第二点很多想法来自Udi Dahan - The Software Simplist

原文地址:https://www.cnblogs.com/kaneboy/p/2436739.html