“模型、狀态和行為特征、場景”和“四象圖”,模組化觀的命名與立象。
模組化原語:四象圖
命名:模型、結構特征、行為特征、場景(及其規約)。
釋義:
模型,描述事物為一組時間函數,蘊藏了與事物相關的所有事實。
特征,從模型上剝離的一組時間函數。特征分為兩大類,一類是結構特征,一類是行為特征。
場景,模型凝聚相應的特征持續一段時間,描述一段時間内與模型相關的事實。場景中隐藏的一些規則、約定,稱之為場景規約。
用法:
一筆一紙,一橫一豎,四象頓生。
一象畫景,三象畫物,物在景中。
二象畫形,四象畫神,形神兼備。
萬象入畫,渾然一體,一目了然。
注:第一象限畫景,即描述場景;第三現象畫物,即描述模型。第二現象畫物之形,即描述模型的結構特征;第四象限畫物之神,即描述模型的行為特征。
諸子百家:
如果你熟悉四色原型,DESC可了解為結構特征,PPT可了解為模型,Role可了解為行為特征,MI可了解為場景。
如果你熟悉DDD, VO可了解為結構特征,Entity可了解為模型,Aggregate可了解為行為特征,Service可了解為場景, Specification可以了解為場景規約。
如果你熟悉DCI,D可了解為模型,C可以了解為場景,I可以了解為行為特征。
如果你熟悉MVC, M可了解為模型,V可了解為結構特征,C可了解為行為特征。
如果你熟悉Web,HTML可了解為模型,CSS可了解為結構特征,JS可了解為行為特征,“頁面”可了解為場景,HTTP可了解為場景規約, URI可了解為場景的命名。
如果你熟悉Database, Table可了解為模型,View可了解為結構特征,Trigger可了解為行為特征,“增删改查”可了解為場景,SQL(關系代數)可了解為場景規約。
如果你對上述諸子百家的解釋一無所知,恭喜你!你可能将在最佳的狀态下,快速掌握四象圖的精髓。
為了有一個感性的認識,以電影為隐喻。Actor(演員)表示模型,Props(道具)表示結構特征,Role(角色)表示行為特征,Script(劇本)表示場景。電影《英雄》中的陳道明是模型(演員),龍袍是結構特征(道具),秦始皇是行為特征(角色),刺傷秦始皇片段是場景(劇本)。
最後也會有兩個簡單的代碼案例(都源自Jdon道友提出的案例),讓你初步感受一下四象圖的作用。
開放課題:
1)描述原語的具體語言
靜态語言,動态語言?指令式語言,聲明式語言?Web給我們樹立了一個極好的榜樣,模型使用HTML描述,結構特征使用CSS語言描述,行為特征使用JavaScript描述,場景規約使用HTTP描述,場景使用URI命名。事實上Android UI就汲取了Web的靈感,将UI的模型及結構特征使用XML描述。
2)特征剝離的方法
如果特征與模型使用同一種語言(比如Java),結構特征和行為結構的剝離需要付出額外的精力,比如前者側重“一緻性”,後者側重“互動性”。而在Web中,結構特征和行為特征的剝離易如反掌。一緻性要求畫面在一段時間呈現相同的風格,這将給使用者良好的界面體驗的必要基礎。CSS的設計者之一Bert Bos,解釋了為什麼CSS高度強調一緻性。
Why “variables” in CSS are harmful?
3)特征凝聚的方法
模型凝聚特征,最簡單的方法就是指派。當模型具有複雜的結構特征時,可以使用“結構型”模式進行凝聚;當模型具有複雜的行為特征時,可以使用“行為型”模式進行凝聚。 凝聚特征的方法遠不止指派和GoF模式,比如JQuery中的selector、 Android中的R.java等等。
4)語言引擎的設計與實作
在不同的“系統”或“層次”之間,可能需要引入“語言引擎”這個概念,語言引擎的工作主要是協調兩個說不同“語言”的“系統”之間的資訊交流。比如Web應用的前端用戶端說的是JavaScript語言,後端伺服器使用是其它的語言(比如Java, PHP等)。Ajax(Asynchronous JavaScript and XML,由Jesse James Gaiiett發明)引擎負責兩者的資訊交流。Ajax的本意是通過JavaScript啟動引擎,發送Request,異步接收以XML的資料格式傳回的Response。現在XML已逐漸被JSON取而代之,因為相對于XML, JavaScript天生對JSON非常熟悉,是自家兄弟。
這裡我修改Ajax的含義使其具有普适的意義。A = asynchronous, J = jabber, A = And, X = X。A 表示異步(同步是異步的特殊狀态),Jabber的含義是“快而含糊不清的話”,X代表是任意對話者将的語言。
當某個層次或系統說的語言(Jabber),對于另一個層次或系統(使用X語言)而言可能就是“快而含糊不清的話(Jabber)”(我們多數人聽老外講話不就如此?老外聽我們說話亦然!),此時就需要一個“語言引擎”進行翻譯,使兩者流暢地交流。語言引擎有兩個工作模式:異步模式和同步模式。
對于Web UI來說,JavaScript為了自己的話能夠被伺服器(比如使用Java編寫的伺服器)聽懂,使用Ajax語言引擎告知自伺服器自己說了啥,要做什麼。
對于Web Server(比如Java編寫的伺服器),為了Database能夠聽懂自己的話,知道自己想要些什麼,做些什麼,也需要構造一個Ajax引擎。語言引擎如果足夠智能,可自動切換工作模式。比如在同步工作模式下,與SQL資料庫建立會話;在異步工作模式,與NoSQL建立會話。
語言引擎的設計者需要具備精通資料庫語言和伺服器使用的語言,才可能建立通用的語言引擎。這個有能力的人可以考慮怎麼實作,将其開源奉獻給社群。 我目前是不知道啦。語言引擎不是Object/Relation Mapping,多多借鑒Asynchronous JavaScript and XML才是正道。
5)架構風格的設計與實作
Roy Thomas Fielding的博士論文《架構風格與基于網絡的軟體架構設計》是一篇極好的文章。李锟、廖志剛、劉丹、楊光的翻譯也非常到位,感謝他們無私的奉獻。我提出四象圖的靈感部分(模型)源自于這篇論文對“資源”的定義,還有一部分靈感(特征)源于曾經對系統“特征向量空間”的癡迷。
Fielding在文中提及,“更精确地說,資源R是一個随時間變化的成員函數MR(t),該函數将時間t映射到等價的一個實體或值的集合,集合中的值可能是資源的表述和/或資源的辨別符。”“REST對于資訊的核心抽象是資源。任何能夠被命名的資訊都能夠作為一個資源。”
在四象圖中,Resource猶如“凝聚特征的模型”; Representational State表示“模型進入的場景”; State Transfer Protocol表示“場景的規約”;URI則是對“場景的命名”,其應綁定恰當的語義。
四象圖與REST描述具有相似的“畫面感”。 資源的表述性狀态是一個持續一段時間的畫面,狀态轉移協定切換各個畫面。模型進入場景持續一段時間的畫面,場景規約切換各個畫面。兩者之是以,具有相似畫面感,是因為模型與資源的定義都是時間函數,是一個随着時間變化的概念。
體驗與感受REST架構風格、四色原型、GoF設計模式,想象與其提出者進行交流,聆聽、汲取其智慧,是我提出“四象圖”的源泉。Web是一個成功的REST架構,運作了幾十年。碰觸Web,與接觸TCP/IP協定棧、信号與系統、香農的資訊論、機器學習一樣,都令我感到震撼,開闊了原有的視野。
架構風格的設計與實作,我也是個在不斷學習的初學者。之是以列出這個課題,是因為我覺得其非常重要,不可或缺。
6)程式之道:象數理
Niklaus Wirth提出公式“程式 = 資料結構 + 算法”,我認為這個公式少了一個東西,必須顯現出來,即“模式”。古人有“象數理”之說,“象”在程式中抽象為“資料結構”,“數”抽象為“算法”,“理”抽象為“模式”。
“象”可以描述變量,過程,對象,函數,程序,事實,……,基于不同的“象”(資料結構),我們需要思考相應的“數”(算法),發現“象數”之後的“理”。這是無止境開放的課題,我們可能永遠都無法找到永恒的真理。
模組化原語和程式之道的來龍去脈,可以參考文章《領域驅動設計之我見》和《Hello, World! 我心中的道》,但那兩個文章充斥着混亂和錯誤,有時間可以了解一下,沒有時間,看這個文章就行了。這些是我提煉、加工後的結果。
提出“六大開放課題”,因為其與“四象圖”在虛拟世界中的落實息息相關。有空我會寫一些特征凝聚的代碼例子,作為參考。uda1341的設計的作品完成差不多了,可讓他普及一下程式之道這個課題出現的新方法論:Fact-Oriented Programming。
希望有更多的人,了解和使用四象圖,并對随之提出的“六大課題”感興趣,去研究和解決他們。
歡迎轉載此文。最好注明原出處。
一個中心,兩個基本點。即以“模型”為中心,以“特征”與“場景”為兩個基本點。
特征,表示描述觀察事物的角度,主要有兩個角度:狀态(結構)與行為(功能)。
場景,表示使用哪些角度觀察和使用模型(模型凝聚特征),描述特定時間内所有與事物相關的事實。
MVC和DCI的提出者Trygve Reenskaug提倡用可讀性極佳的代碼直接捕獲使用者心中的模型,我采納了這個觀點,同時在編寫原型時借鑒了四色原型及DCI的部分思想。
這裡先陳述我的一些思考和觀點,可能與一些經典著的定義有所出入,随後再将代碼貼出來。
1)領域是客觀的,不以人的意志為轉移,但人之于領域具有能動性,可以認識和改造它。
2)領域模型是主觀的,展現了程式員對領域的認識,是程式員心中對領域的素描。
3)使用者需求是主觀的,展現了使用者對領域的認識,是使用者心中對領域的素描。
4)領域模型需要捕捉和包容使用者需求。領域模型與使用者需求的關系十分重要,下面展開來講。
“使用者需求”是對領域的“素描”,使用者的需求來自對領域的“訴求”,這些訴求往往是深刻的,因為其來源于使用者對領域長期觀察和使用的經驗,比起我們程式員,一般更完整、更真實地接近領域的本質。我們對“使用者需求進行素描”,就是“借鑒使用者的寶貴經驗”,可以更快、更好地素描客觀領域,這可以說是一條認識(未知)領域的捷徑。但是當使用者需求不明朗或不清晰時,我們需要超越“使用者需求”,對領域進行深入的摸索,去尋求更清晰的視角,對領域進行刻畫。
此外,“使用者需求”不能等同于“使用者”,捕捉“使用者心中的模型”也不能等同于“以使用者為核心模型”,這是不同的概念,不能忽略其差異。《老子》書中有個觀點:有之以為利,無之以為用。在這裡,有之利,即建立領域模型;無之用,即包容使用者需求。舉些例子,一個杯子要裝滿一杯水,我們在制作杯子時,制作的是空杯子,即要把水倒出來,之後才能裝下水;再比如,一座房子要住人,我們在建造房子時,建造的房子是空的,唯有空的才能容乃人的居住。我們建立領域模型時也要将使用者置于模型之外,這樣才能包容使用者的需求。
現在嘗試提出一套更淺顯的模組化原語,來诠釋我的領域模組化觀。
前幾天,還打算從系統的角度去解釋四色原型(分析模式)、領域驅動設計(設計模式),發現這種做法可能會比較枯燥,放棄了。
現在,結合隐喻的方式,看是否能将兩者解釋得通俗易懂,并且提供一組領域模組化的原語,作為分析、設計、實作階段的通用語言。
大家先回想熟悉的畫面:
1)花木蘭從戰場凱旋歸來,辭去将軍之職,脫下戎裝,現出女兒身。
2)花木蘭戰場上英勇作戰,披上戎裝,行将軍之職,無人知曉是女兒身。
四色原型的描述:戎裝是Desc,花木蘭是PPT, 将軍是Role,作戰是MI。
DDD的描述:戎裝是Value Object, 花木蘭是Entity, 将軍是Aggregate, 作戰是Service。
DCI的描述:花木蘭是Data, 将軍是Interaction, 作戰是Context。
生活化的描述:戎裝是“道具”,花木蘭是“演員”,将軍是“角色”,作戰是“劇本”。
在上面的分析之上,提出四個模組化原語:
狀态特征(state feature), 别名特征(feature)。
模型(model),别名實體(entity),事物(thing)。
行為特征(behavioral feature),别名角色(role)。
場景(context),别名服務(service)、活動(activity)。
模型是領域的核心。
狀态特征是從模型(model)上剝離的具有“一緻性”的狀态特征。
行為特征是從模型(mdoel)上剝離的具有“互動性”的行為特征。
場景中模型将“剝離”的狀态和行為特征重新“凝聚”起來,互相作用,完成任務。
--------------------------------------------------------
采用這套模組化原語從新設計“圖書館”這個案例。
0) 工廠:CardFactory
----------------------------------
1)模型: Libarary, Card, Book
2)狀态特征:CardType、BookDetail
3)行為特征:BorrowedBook
4)場景:BorroweBook、BorrowedBookReturn、BorrowingIterm
模型,将現實中最核心的事物自然映射到領域模型中。
狀态特征的剝離,看模型的部分屬性是否具有“一緻性”。上面的CardType, 剝離的有必要,但BookDetail則沒有明顯的業務需求,可以不剝離。
行為特征的剝離,看模型的部分行為是否具有“互動性”。BorrowedBook實際上并不表示“互動過程”,而是“互動結果”,但能反映“互動”特征,是以實作時可這樣表達。
場景:BorrowingTerm包含場景的前置條件、互動限制,展現業務規則。DDD的術語好像是規約(Specification),是一種深層次的重構。之前我幾乎無意識地把“借閱規則”放在一塊,看來是對了。
參與場景時,如果模型符合場景的規約,模型就會凝聚剝離的特征—狀态特征(根聚合)和行為特征(扮演角色),成為真正的“對象”,“對象”在彼此之間形成的關系網絡中傳遞消息(可采用事件驅動),完成任務。
總結一下模組化過程:
1)從業務中将最核心的事物自然映射為領域中的“模型”。
2)從“模型”上剝離出狀态特征和行為特征,剝離的基本角度是“一緻性”與“互動性”。
3)根據在場景中業務規則,“模型”重新凝聚剝落的“特征”,成為真正的“對象”。
4)“對象”之間互相“傳遞消息”,完成任務。
1)面向類(抽象的對象),不是真正的OO, 面向對象(靜态的對象),也不是真正的OO;類+對象+時間,才是真正的OO。
2)關系代數,關系的定義不是指外鍵,外鍵隻是外部對關系一個字段屬性的限制而已,字段屬性有很多種限制,外鍵隻是其中一種。
3)關系的數學描述是一個集合,在OO中,等價于“類及其所有對象之和”。關系運算,即對“關系”的操作,是真正意義上對“對象”的操作。
4)目前的資料庫沒有時間觀,目前的OO也沒有時間觀,但是關系代數,有!
5)GoF設計模式沒有時間觀,其靈感源于《建築的永恒之道》,建築是一個空間藝術,永恒試圖超越時間,即追求特征不變性。
6)沒有時間的OO世界觀中,狀态共享是并行之道;在有時間的OO世界觀中,狀态共享隻是一種特例,消息傳遞才是并行之道。
7)掌握并行程式設計,最好能掌握愛因斯坦的廣義相對論,在實體意義和數學意義上深刻認識時間和空間,如果不能,也要嘗試去了解,因為并行
程式設計實際上是時空觀在計算機上的落實。
8)數學是一個偉大的學科,是所有學科中最“無為”的一個學科,為其他學科提供必要的工具,可謂“利萬物而不争”。不要去批判數學思維,要去批判那些對數學有誤解和偏見的思維。因為“無為”,數學“無所不為”,被人封為“無冕之王”,功高震主,“哲學”的霸主地位岌岌可危。但“數學”本身并不想争奪“帝位”,是它的崇拜者,要把它推向至尊的王位。“數學”的崇拜者,想通過讓“數學”登上寶座,來擷取更多的榮耀與話語權,但忘記了“數學”崇尚“無為”。
9)比如,數學上一個矩陣,可以是一堆無意義的資料的堆積,可以是一幅圖像的表示,可以是一個電路的描述,可以是一個化學反應方程組的表示,可以是一個網絡的描述,可以是一個系統的描述,... 這就是“數學”,“無為”而“無所不為”。
10)我喜歡數學,但不是數學的崇拜者,更不想通過讓“數學”登上寶座,使自己擷取更多的榮耀,因為“數學”根本不在乎這個“寶座”,那是其崇拜者自己心中的欲望而已。
11)我也喜歡領域模組化,也試圖提取一套模組化原語。這個文章,就是開始做這個嘗試,關于實施的細節,需要更多的思考和讨論,我會先寫一部分,抛磚引玉。
先說說,一些關于在場景中模型凝聚“狀态特征”和“行為特征”的思考,以後會更多的論述。
1)在複雜的場景中,模型對狀态特征的凝聚,可能需要使用結構型模式;對行為特征的凝聚可能需要使用行為型模式。
2)比如,使用組合和修飾器模式去凝聚一些狀态特征;使用指令和觀察者模式去凝聚一些行為特征。
3)模型的建立可能需要使用建立模式,比如Card,使用CardFactory進行建立。
4)特征的建立也可能需要使用建立模式,比如行為特征(角色)在諸多場景中類似時,就需要使用“動态代理工廠”進行建立,控制特征類的數量的膨脹。
我嘗試提出的這套原語意圖在“分析、設計、實作”三個階段通用,分析人員、設計人員、實作人員可以很自然地了解它,使用它。
這裡解釋一下定義這套術術語背後的思考過程。
1、模型,是事物的含義。但事物這個概念太廣泛了,不宜直接拿來用,就像在REST中,使用資源這個詞去代替事物,事物可作為别名。
那麼為什麼不選擇DDD的Entity、四色原型的PPT或者DCI的Data呢?因為我們是在建立一套模組化原語,最核心的概念自然要與模型有關,除了“模型”,我實在想不出更貼切的詞彙了。模型,是模組化的根本。
2、特征,描述事物(模型)具有怎麼樣的特點。特征既具有生活化的氣息,也是一個在被各種學科廣泛使用的術語,淺顯而深刻。
比如矩陣輪、系統論上,特征向量、特征值、特征向量空間是出現頻率極高的詞語,常用于描述各種系統。我們使用特征來刻畫、描述我們的模型。這裡DDD的Value Object, 四色原型的Description,在直覺上,在深刻性上,都遠不如這個詞彙。
3、場景,這也是一個生活化的語言,需求分析時,經常會有這個說法,有哪些業務場景。場景是一種活動,但活動與事物一樣,太廣泛了,隻能作為别名。
這三個詞彙,我個人覺得很好,因為它們既直覺,又具有深刻性。
4、特征,分為狀态特征和行為特征,代表從“狀态”和“行為”兩個次元去觀察“模型”,它們是從“模型”身上剝離出來的,除了它們本身具有獨立性和可複用性,更為重要的是使“模型”更為精煉。
5、在場景中,“模型”凝聚與此時此景有關的“狀态特征”和“行為特征”,成為一個活生生的對象,與其他對象進行互動,完成任務。
這套原語的數學描述。
1)模型,表示為一組時間函數,包含狀态特征和行為特征。
model = {f1(t),f2(t),...};
2) 特征,從模型的一組時間函數中,提取相對獨立的狀态特征和行為特征。
state = {f1(t),f2(t),...};
behavior = {f1(t),f2(t),...};
3) 場景,在場景模型凝聚特征持續一段時間(如從t0時刻到t1時刻)。
context => model-state-behavior = {f1(t0->t1),f2(t0->t1),...}。
借鑒四色原型的形象思維,使用四個原語。
在一張紙上畫一個四象圖,一橫一豎的笛卡爾坐标平面。
1)把領域中的核心事物映射到四象中,放在第三象限,作為模型;(可以塗上綠色)
2)把領域中的業務場景映射到四象中,放在第一象限,作為場景;(可以塗上紅色)
3)考慮所有場景,将模型的行為特征剝離出來,放在第四象限;(可以塗上黃色)
4)考慮所有場景,将模型的狀态特征剝離出來,放在第二象限。(可以塗上藍色)
不太一樣,我的出發點是以“模型”為中心,以“特征”與“場景”為兩個基本點。拿那個花木蘭的例子分析一下。
大家熟悉的畫面:
分析過程,設計過程,實作過程将呈現高度一緻。
1)很容易識别出“花木蘭”是“模型”,放在“四象圖”的第三象限,塗以綠色;
2)很容易識别識别在戰場“作戰”是“場景”,放在“四象圖”的第一現象,塗以紅色;
3)從“花木蘭”這個模型身上剝離出“狀态特征”,即“戎裝”,放在第二象限,塗以藍色;
4)從“花木蘭”這個模型身上玻璃出“行為特征”,即“将軍”,放在第四象限,塗以黃色。
再分析一下圖書館這個領域中的借閱場景,讀者是不在這個圖書館領域中的,讀者是圖書館領域的使用者和觀察者,是圖書館領域模型的使用者。
1)圖書館、圖書卡、圖書,是“模型”,放在“四象圖”的第三象限,塗以綠色;
2)卡的類型,表征“狀态特征”,放在“四象圖”的第二象限,塗以藍色;
3)被借閱的書,表征“行為特征”,放在“四象圖”的第四象限,塗以黃色;
4)借閱場景、借閱規則,是場景,放在“四象圖”的第一想象,塗以紅色。
“四象圖”不同于四色原型的畫圖方式,與UML的畫圖的角度差别更大。這是這套原語的“象”;如果具備一定數學常識,可以了解這套原語的數學描述,即“數”;實際上也可以從“理”即純粹邏輯的角度來剖析這套術語,這個我着墨較少,畢竟“理”隐藏在“象數之中”,要解析出來,需要借助一些邏輯觀并探讨世界觀,這可能會使這套原語失去“親和力”,是以暫時先不多說。
這套原語對分析人員、設計人員、開發人員都具有“親和力”,甚至對于外行都具有親和力,容易了解,“四象圖”,這個工具,可以讓他們幾乎不用思考(不思考是不可能的,隻能說解放了一部分腦力)就可以進行分析、設計和實作。如果能了解其數學描述,了解其背後的邏輯觀,那當然更好,但不會太影響“四象圖”的使用。
是以,“模型、狀态和行為特征、場景”和“四象圖”,可以視為對模組化觀的命名與立象,渾然一體而泾渭分明,強調了模型的整體觀和動态性,不像UML将模型割裂為類、狀态圖、互動圖、用例等等,而且UML的狀态圖與互動圖不能直接落實為代碼,而狀态特征與行為特征可以,兩者實際上是不能等價視之的。
四象圖的整體性和動态性,展現在用一張圖形象描述了領域中可能出現的所有靜态或動态的畫面;模型、狀态特征、行為特征,橫跨整個領域;場景根據業務規則(規約)選取模型,模型在此時此景内,凝聚了相關的狀态特正、行為特征,進行協作,完成任務。
與四色原型看起來很像,但背後的思考卻已經發生變化了。
1)這套原語的核心是以“模型”為中心,不同四色原型或DCI以“角色”或“場景”為中心,是把“角色”以及“描述”看作模型的附屬物。
2)狀态特征和行為特征,是因為具有獨立性,從“模型”身上剝離。戰場上的花木蘭身上的“戎裝”(狀态特征)和“将軍之職”(行為特征),是可以剝離出來複用的。戎裝可以别人穿,将軍可以别人當。
3)行為結果可以用來反映行為特征,行為過程也可以用來反映行為特征。角色是一個名詞呀,能表示行為特征?實際上角色這個概念也是行為結果呀。行為特征的刻畫方式,可以通過“角色”(行為結果),也可以通過“(時間)函數”(行為過程)來刻畫。
4)場景是在一段時間内,模型根據業務規則凝聚相關的特征(披上戎裝(戎裝不一定是當将軍的人才可以穿的),行将軍之職)進行作戰。
5)例子隻是為了形象說明,便于大家了解。如果你看看數學描述,了解起來應該就不會有什麼困惑了。
6)忘記四色原型、DCI、DDD等琳琅滿目、層出不窮的詞彙吧,提出這幾個原語的一個目标就是希望消除這些buzzword,為大家騰出更多的時間和精力思考更優雅的技術實作。
這個不是角色,是一個活生生的對象,角色是行為特征的抽象。
模型(花木蘭)凝聚了狀态特征(批上戎裝)和行為(扮演了将軍),成為一個活生生的對象(真正的對象),在戰場上進行戰鬥。
不是将軍(角色)在戰鬥,完整的描述是一個披上戎裝身為将軍的花木蘭在戰鬥。
如果你把模型凝聚特征後的對象,了解為角色,實際上還是以角色為中心,還是停留在一個“抽象”的層次,在場景中,模型凝聚特征後成為一個活生生的對象,一個活生生的生命。
你說的兩個過程不一樣:一個是用來“刻畫”特征,一個是表示模型“凝聚”特征的過程。
行為特征可以表示為一個類(比如角色、比如事件監聽器),可以表示為一個函數(比如function() {}),
狀态特征可以表示為一個類(比如顔色、金額),也可以表示一個函數(比如2t+3)。
特征可以有更多的表達形式,甚至我們還不知道的形式。
行為特征與狀态特征的差別不在于其在表現形式,在于從模型剝離出來的角度。
狀态特征考慮模型部分特征的“一緻性”從“模型”上剝離;
行為特征考慮模型部分特征的“互動性”從“模型”上剝離;
狀态特征與行為特征,都是模型的特征,嚴格區分它們不是特别重要,
倘若特征剝離從兩個角度都說得通,此時區分是模型的狀态特征還是行為特征就沒有必要了。
特征剝離的基本目标有兩個:1)複用狀态和行為特征;2)使模型更精煉。
注入,是模型在場景凝聚特征的一種方式,狀态和行為特征都可以。
關于模型在場景中凝聚特征的方式,簡單的可以通過傳參的方式。
比如把狀态特征和行為特征通過作為模型的構造參數傳遞進去。
還可以考慮使用設計模式進行特征凝聚,比如通過模型綁定事件監聽器來凝聚行為特征(觀察者模式),通過組合方式凝聚多個狀态特征(組合模式)。
在前面,我已經寫了一點關于場景中模型如何凝聚特征的思考。
結構型模式和行為型模式分别是模型凝聚狀态特征和行為特征的有效工具,可以根據場景特點,靈活選擇。
從模型上剝離特征(分),模型凝聚特征(合)的方式,是一個開放的課題,我隻是在方向上,考慮了個大概。比如剝離的角度,一緻性、互動性;凝聚的方式,結構型模式、行為型模式等。
你可以使用這套原語重新組織你的論壇代碼。我在這裡開個頭。
模型:帳号、文章、論壇
狀态特征:帳号類型、文章類型、文章狀态(置頂、鎖定等)、論壇狀态(主題總數,文章總數,最新的文章ID等)
行為特征:
場景:發文章、跟貼等
這裡模型好像沒有明顯的互動特征,業務場景相對單一,沒有剝離的必要。
假如該帳号不僅可以用在論壇,也可以用在圖書館系統中,
那麼帳号的行為特征就可以剝離出來,分成兩類,一個與論壇有關的,一個與圖書館系統有關的。
發現圖書館的那個例子,有問題,需要修正一下。
圖書卡這個現實中的事物,在系統中的映射實際上是帳号。
圖書卡是使用者在現實中使用的工具,帳号是使用者在系統上使用的工具。
是以把Card全部改為Account,就可以了。
而且Account上的行為特征也可以剝離,如果Account的用途不僅僅在圖書館領域上,僅僅考慮圖書館領域時就不需要剝離。
文章與圖書基本上很相似。但還是有差別,文章沒有依賴場景的行為特征,圖書卻有(BorrowedBook)。
行為特征,一種直白的解釋就是模型依賴于場景的用途,跟之前讨論的角色很相似,在定義行為特征時,角色是作為其别名的,是以關于角色的認識仍有效。
關于特征已經寫了不少,下面再寫一點關于場景的思考,算是終結吧。因為我已經傾囊相贈,拿不出更好的東西了。
場景可分為兩大類:查詢和指令,前者是觀察模型及其特征,後者是讓諸多模型凝聚特征一起做事情。
場景中模型凝聚行為特征的方式,可以是EDA,或所謂的Domain Events。
這套原語也可以從MVC的角度去了解。MVC的M表示模型,VC可以了解為場景,V和C将場景分為兩大類,V表示從觀察模型,C表示從控制模型。
從系統論的角度看,模型與特征(結構/狀态和行為兩個角度)是對系統的内部描述,場景時對系統的外部描述。
外部描述可以從很多個角度進行分類,比如輸出、輸入;比如查詢、指令;比如視圖、控制器;比如讀和寫;比如視圖和觸發器;其實它們是相通的。
這套原語用于了解和學習界面設計、資料庫設計、領域模型設計都是可以的。原語,承載的是一種思想,一種看事物、看系統的思想,不會在乎你用它來看那種具體的東西,比如界面、比如資料庫、比如領域,因為它是模組化原語,不僅僅是資料庫、界面或領域的原語,隻要你想用,就有用。
這套原語可以從MVC、CQRS、DCI、四色原型、DDD、EDA、Domain Events、REST等甚至更多我們都還不知道的角度去了解和使用,原語本身不會去限定使用原語的角度,更不會去限定原語具體的實作方式,因為這套原語背後的數學描述實際上是“無為”的。