我是个程序员,这是一篇从程序员角度来分析SOA与OOA的以实例为基础的文章,并非理论上YY。但仅代表我现阶段的观点。我觉得从这个观点出发理解的SOA对我个人架构变程是很有帮助的。希望您观后也有所收获,若您有不同的看法高见希望留下您的笔墨。
这里分析的对象是user,一个在企业应用程序中非常常见得对象。我们围绕这个对象展开讨论,对比一下在OOA概念中与SOA概念中user及其相关功能的代码实现。
1. OOA 实现:
对于OOA实现我们首先想到的是User是“人”(不考虑电脑作为User身份以机器人形势自动完成操作)。既然User是人那么这个对象就应该从“人”对象继承,“人”具有的属性有“姓名”,“电话”,“住址”等,而User作为用户则需要添加属性“用户名”,“密码”。
有了User对象,对于系统来说我们就要操作这个对象。最简单的操作无非“添删读改”,我们可以直接继承一个接口叫IBasicOpertor,也可以继承四个接口IInsertable, IDeletable, IReadable, IUpdatable 这属于个人风格和原子化程度问题。 有时也会依据特殊的需求选择继承(如果考虑了特殊需求,这里实际上就与业务结合比较紧密了)
有了对象,有了操作我们就可以在业务层使用了。模拟使用方式如下(c# 语法)
User user = new User();
user.UserName = "Oceanson";
user.Password = "就不告诉你";
user.Name = name;
user.Phone = phone;
....
user.Insert(); //将用户对象添加到数据库
User user2 = new User();
user2.Read(userName,Password); //用userName 和 password从数据库填充对象
user2.Password = "打死也不说";
user2.Update(); //更新对象
user2.Delete(); //把添加的对象删除
我们可以看到,调用思路还是比较清晰的,但是Read函数显得不太雅观,好像和整体风格不太一致,代码的儒雅性遭到了破坏。
2. SOA实现
就SOA实现,User所需要保存的属性信息还是不能少的。 User同样从“人”对象继承. 但是对User的操作控制就完全不同了。
OOA中对象本身完成对自己的操作,对象本身封装它所需要信息与操作。而SOA的思想是Service,Service负责对对象进行操作,控制对象。这是一个非常重要的抽象分离,对象只需要封装信息,而对对象的操作由专门的操作者来实施。
这样我们就需要一个IUserService的服务接口和第一个UserService的实现。 IUserService需要包含对User的基本操作 int IUserService.Insert(User user); Bool IUserService.Delete(User user); User IUserService.Read(string userName,string password); User IUserService.Update(User user). 这类Service的实现针对不同类型或者有特殊需求的业务可以有多个IUserService的实现,这样一来业务捆绑的问题也解决了。
下面是业务层对普通用户的操作
User user = new User();
user.UserName = "Oceanson";
user.Password = "就不告诉你";
user.Name = name;
user.Phone = phone;
.....
IUserService userService = new UserService(DBInfo); //这里把具体的数据库信息通知UserService,当然UserService也可以自己去配置文件读取数据库配置信息。
int userNativeId = userService.Insert(user); //新建用户, 返回新建的用户在数据库中的索引
User user2 = userService.Read(user.UserName,user.Password);
user2.Password = "我招了";
userService.Update(user2);
userService.Delete(user2);
整个实现从风格上看比较统一。而且分离了持久化与操作的关系,并脱离了业务捆绑。
3. 补充
对于OOA来说User可能还会自包含其他的一些信息,比如Company对象(注意 是一个对象) ,来说明User的Company
这样我们可以在业务层如下使用
Company company = user.Company;
这是一段很漂亮的代码,但对于SOA来说未必这样实现。
我们知道从数据库设计角度User表可能会有Company_Native_Id这样的字段来纪录用户所在的公司。于是我设计的SOA中的User对象就会直接映射这个字段Company_Native_Id
对于Company信息的操作访问是ICompanyService的职责。
代码变为
ICompanyService companyService = new CompanyService();
Company company = companyService.Read(user.CompanyNativeId);
这里对CompanyService的实例化行可以抽象控制到ServiceAgent或者ServiceController这样的对象里去统一控制,留下的那一句就代码风格来说并不比OOA的那个得到Company的方法繁琐,而这么做的好处是我们可以省去一个PV转换。我们可以用某种方式(比如Hibernate思想)直接从数据库反射出一个User对象,然后用风格统一的Service去操作它。整体架构一下子清晰了许多而且有可能完全自动生成(我理解spring的思想)。
4. 代码对象对比user+company 对象越多越可以体会SOA清晰简单的优势,直接读这个表可能比较费解,这个表的确也没有从各个角度来分析,有待更新,但在认真阅读上面3节后相信可以理解我想要表达的东西。
OOA | SOA | |
实现对象 | userPO,userVO,userPVConvert | user |
companyPO,companyVO,companyPVConvert | company | |
IUserService | ||
ICompanyService | ||
5. SOA优势总结:清晰的架构,灵活的捆绑,高效简洁的代码,容易在各个层上分清职责(比如边界input的Check,Handler上做统一的Exception处理和log等)