2011年5月31日星期二

UseCase到領域建模

前言
最近拜讀邱郁惠老師的大作「學會UML/OOAD,這樣開始就對了」,不禁想起從UseCase到領域模型曾是我的一大瓶頸。也許會有人覺得奇怪,這中間不就是名詞轉化為類別,動詞轉化為函式…。我只能說絕不僅是如此,這裏就借用邱老師書上第一個使用者案例,概說一下我的想法。

使用者案例
用例名稱:會員登入
啟動者:會員
支援者:

主要流程:
  1. 會員輸入電郵與密碼
  2. 系統確認會員身分之後,出現歡迎訊息
替代流程:
  1. 資料不完整:客戶端提醒會員填入資料,直到資料完整才傳送到伺服端
  2. 驗證失敗:累積5次登入失敗,即鎖定,並出現請會員主動聯絡系統管理員的訊息
企業規則:
  1. BR1:以會員電郵做為會員代號
  2. BR2:密碼採用MD5儲存
  3. BR3:會員累積5次登入失敗,即鎖定該會員帳號。只要登入成功,即失敗次數歸零
  4. BR4:一個人只能申請一個會員身分
議題與其他:
  1. 帳號密碼變更是否為一使用者案例
領域模型
取自四色原型的觀念,模型必須區分靜態與動態。像PPT這種靜態的物件其屬性應該很少需要修改,所以登入的資訊不適合與會員放於一塊,所以拉出一個較為動態的物件MemberLogin,較為適當。
取自DDD的觀念,規則最好可以獨立成Spec物件,這樣設計時自然會變成可動態抽換,而且說不定日後鎖定的規則不是5次,或再加上間隔時間的限制也說不定。
MemberLoginStatus,也許最後設計時只是個字串、長整數、enum之類,但為了分析上的清晰,我還是傾向將它獨立成類別。
最後的模型圖如下:

2011年5月17日星期二

權限模型思考之二

前言
在理解Rhino.Security的設計理念後,我希望為寫找更多的理論基礎,好讓我不要重複的思考這個問題。所以又找到了Enterprise Patterns And MDA這本書中,關於PartRelationShip的描述。以證明照著這麼設計準沒錯。

PartyRelationShip Archtype
PartRelationShip這種Archtype這麼定義的,所以有人員或組織(Party),都必須建立角色 (PartyRole),PartyRoleType,就是所謂的角色檔。透過角立建立起彼此的關係 (PartyRelationShip),PartRelationShipType就恕我想像力貧乏,不能想出適合的需求。

整合
將兩者整合會推出一個較大的模型,足以代表主流的權限系統觀念
想像案例
某間超市的管理系統。計有經理、店員、會計三種職位,以及5位職員。而經理可以做店員、會計的工作。
首先因為不是什麼複雜的系統,所以沒有Party,只有Employees。而Duties就是系統的角色檔。
Duries有階層概念,所以自關聯。這裏要注意的是,一般權限設定是下層的群組可以繼承上層的權限,但這裏反倒是上層的Duty權限愈大。

2011年5月15日星期日

權限模型思考之一

前言
權限系統可以說是各系統最基本的部分,在領域知識裏也最容易讓人理解,所以在研究模型時,就從這裏開始。我先從達人Ayende那下載了 Rhino.Security來研究,在搞清楚來龍去脈後,再配合RBAC模型,甚至是MDA中的PartyRelationship也就比較清楚。

RBAC
先讓我們搞清楚什麼是RBAC,基本的概念圖如下。意思是不論是Subject(個人)或Orgaization(組織),都必須透過Role去取得 Permission所定義的Operation。Session還不明瞭其用意。整個圖的最複雜的,就是Role Hierarchy。子代角色可以繼承父代的權限,然後一人可以多種角色。

Rhino.Security
先來看一半的ER Model。UsersGroups就是Role,伴隨著自身關聯構成Role Hierarchy。UsersGroupsHierarchy則是設計考量,畢竟從單一Table取出整顆Tree的所有結點是很不好做。Users透 過UsersToUsersGroups找到扮演的角色,從而知道關聯的權限與操作。應該是基於實際應用的考量,因為Ayende允許User也可以沒有 角色就有權限。至於Allow是指是否可以操作,Level是指兩種以上的角色對某一權限的操作衝突時,何為優先。

再來看另一半的ERModel,這裏是在定義可以操作的物件群組。例如Opereation定義/Employee/Edit這種操作,但它是作用在 Employee這種EntityTypes之上。更進一步,可以分類EntityTypes成EntitiesGroups。 EntitiesGroups還可以有Hierarchy的觀念,例如Employee與它的屬性。
EntityReference與EntityTypes之間,需要一個EntitySecurityKey區隔開,原因我還不太明瞭。 EntityReferencesToEntitiesGroups則是建立物件的群組關係。然後與之前相同 的,EntityGroupsHierarchy是協助產生EntitiesGroups的樹狀結構。Permission不僅能設定 EntitiesGroups,也能單對EntityReference。


API
Rhino Security做了個有趣的API讓我們使用,以一種近乎人類語言的方式封裝了權限的操作

permissionsBuilderService
   .Allow("/Employee/Edit")  //允許什麼樣的操作
.For("Secretary") //什麼角色,經理
.On("Employee") //作用在什麼物件群組
.DefaultLevel() //優先級最低
.Save();

authorizationService.IsAllowed(secretary_A,employee_A,"/Employee/Edit"); //true

2010年5月24日星期一

Entity 與 Value Object的一點思考

前言:
  Entity與Value Object是DDD的重點觀念之一。最基本的定義,Entity帶有Identity,Value Object沒有。一個Value Object與另一個Value Object之所以相同,完全是憑它們的屬性。換言之,如果Value Object換了屬性值,兩個VO之間也就不同了。這跟Entity無論怎麼換,只要ID不動,就是同一個物件是不一樣的。
  Value Object的另一個特性就是它是immutable的,亦即屬性不可異動,這倒跟Entity的ID是immutable是同涵意的。如果破壞了immutable,物件就不再是之前的那個物件。

Enterprise Pattern:
 然後我又看了一下POEAA內,對Value Object的定義。沒有ID的小物件,憑屬性辨識,例如Money,DateTime,最合乎的資料庫設計是Embedded Value或Serialized LOB,換句話說就是將VO的屬性內嵌到Table的欄位中。所以Value Object只是Entity的一個Column值,而不是一個外鍵參考是沒錯了。

Address: 
 為什麼沒事提這個東西,因為DDD說Address是一個VO。因為如果有一群人同住在一個地址,當其中一人要搬出去了,他不能改它的住址,因為只要換了,就會變成大家都換住址了。我如果用上述的觀點來看,住址如果是VO,那應該是每個人都有一個地址VO,換換Column的值怎麼會影響到其他的物件。
 那如果是大家共用一個住址,那又是什麼,不就是Entity嗎?每個人用一個外鍵關連到住址。這讓我腦子登時混亂起來,這是一個immutable的Entity嗎?

結論:
 最後我還是接受POEAA的觀念,只有一些小物件適合當VO。最好不要浪費時間分析是否是個Value Object,為DDD而DDD是沒必要的。

2010年2月7日星期日

用四色原型改寫DDD中的範例模型

Domain Model Driven
在Domain Driven Design的第164頁,上面有一個貨櫃運送的Domain Model Diagram
這張圖表達的是一個貨運公司的領域模型:
  1. 每個貨櫃關連很多Cutomer角色,如運送者、接收人、付款人
  2. 貨櫃運送過程中會產生很多HandlingEvent,如上貨、卸貨、送達
  3. HandlingEvent幾個組成一個CarrierMovement,由某Location到某Location
  4. 貨櫃抵達接收後,會產生一筆DeliveryHistory
  5. 運送過程可以改變行程,但最終必須符合DeliverySpecification規定的送達時間及目的地
有了這張圖,便可發揮DDD的理論進行設計。但我疑問的是,這張是怎麼推論出來的,只是翻遍全書也沒說明。

四色原型
在學習四色原型漫長一段時間後,我終於有點領悟可以推論出以四色原型改寫過的模型。

第一步先建出紅色的時間序例事件,CargoBook會有很多的CargoShipping,這個取代了原來的HandlingEvent。自關連的CargoShipping表示了一系列的事件。貨物抵達後,需要產生一個DeliveryHistory。
接下來推論角色,依據角色是一種狀態,以及一個物件可以扮演多個角色的原則,推論出這張圖。
重要的兩個綠色PPT
一系列的運送動作,可以組成一段行程,行程又由Location組成,這裏用了兩個藍色的Desc表達出這是同一類型的觀念。
最後來考慮DeliverySpecification到底做了什麼事。總歸來說它就是一個規範,規範了抵達時間與地點,但可以有更「複雜」的使用。看過後面的Specification章節,我可以猜測應該有個IsOverDue的Method,協助判斷貨物到期了沒。所以我就想,在CargoShipping的產生過程中,應該也要有個PlugIn協助做這件事,然後也許我應該再開一個角色叫OverDueCargo吧。

最終的成果

結尾
四色原型的好用真是難以說明,歡迎有同好來討論。

2010年1月21日星期四

Moment-Interval深入思考

1、每個MI,都會包含一個時間或一段時間
2、MI的連接,代表事件的執行順序

3、是一種Transaction Log
  • 物件的增修改,都是一種Transaction,MI可以替其留下Log

4、類似Transaction Script或DDD的Service概念
  • Service是把無法歸類的邏輯集中到一個類別處理,並賦予Domain的概念。
  • Transaction Script則是結構化設計的概念,將所有Domain物件該做的事皆放至一個類別來處理,所有的Domin物件都只有屬性,沒有方法。
  • 以上兩種類別將會是Stateless
  • MI也是可以集中無法歸類的邏輯,但本身有時間序列及Log的概念,所以不會是Stateless

2010年1月19日星期二

Description的深入思考

1、用來描述性質的類別


2、用來代表一組的PPT

3、用來建立Knowledge Level
Knowledge Level:系統類別可以分成兩種,一種是Operation Level,另一種就是Knowledge Level。Knowledge Level規範Operation Level的運作

例如:我們習慣將特殊化現象時使用繼承

但是這樣畫,更有彈性