從功能實現的細節看SOA與OOA,以及SOA的優勢何在
我是個程式設計師,這是一篇從程式設計師角度來分析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等)