Posted on 2011-02-07 02:56
canonical 閱讀(1538)
評論(0) 編輯 收藏 所屬分類:
設計理論
一種技術思想如果確實能夠簡化編程,有效降低系統構造的復雜性,那么它必然具有某種內在的數學解釋。反之,無論一種技術機制顯得如何華麗高深,如果它沒有
清晰的數學圖象,那么就很難證明自身存在的價值。對于模型驅動架構(MDA),我長期以來一直都持有一種批判態度。(Physical Model
Driven http://canonical.javaeye.com/blog/29412
)。原因就在于“由工具自動實現從平臺無關模型(PIM)向平臺相關模型(PSM)的轉換”這一圖景似乎只是想把系統從實現的泥沼中拯救出來,遮蔽特定語
言,特定平臺中的偶然的限制條件,并沒有觸及到系統復雜性這一核心問題。而所謂的可視化建模充其量不過是說明人類超強的視覺模式識別能力使得我們可以迅速
識別系統全景圖中隱含的整體結構,更快的實現對系統結構的理解,并沒有證明系統復雜性有任何本質性的降低。不過如果我們換一個視角,
不把模型局限為某種可視化的結構圖,而將它定義為某種高度濃縮的領域描述,
則模型驅動基本上等價于根據領域描述自動推導得到最終的應用程序。沿著這一思路,Witrix平臺中的很多設計實際上可以被解釋為模型定義,模型推導以及
模型嵌入等方面的探索。這些具體技術的背后需要的是比一般MDA思想更加精致的設計原理作為支撐。我們可以進行如下抽象分析。(Witrix架構分析 http://canonical.javaeye.com/blog/126467
)
1. 問題復雜?線性切分是削減問題規模(從而降低問題復雜性)的通用手段,例如模塊(Module)。(軟件中的分析學 http://canonical.javaeye.com/blog/33885
)
App = M1 + M2 + M3 +
2. 分塊過多?同態映射是系統約化的一般化策略,例如多態(polymorphism)。(同構與同態:認識同一性 http://canonical.javaeye.com/admin/blogs/340704
)
(abc,abb,ade,
) -> [a], (bbb, bcd,bab,
) -> [b]
3. 遞歸使用以上兩種方法,將分分合合的游戲進行到底,推向極致。
4. 以少控多的終極形態?如果存在,則構成輸入與輸出之間的非線性變換(輸入中局部微小變化將導致輸出中大范圍明顯的變化)。
App = F(M)
5.
變換函數F可以被詮釋為解釋器(Interpreter)或者翻譯機,例如工作流引擎將工作流描述信息翻譯為一步步的具體操作,工作流描述可以看作是由底
層引擎支撐的,在更高的抽象層面上運行的領域模型。但是在這種觀點下,變換函數F似乎是針對某種特定模型構造的,引擎內部信息傳導的途徑是確定的,關注的
重點始終在模型上,那么解釋器自身應該如何被構造出來呢?
App ~ M
6.
另外一種更加開放的觀點是將變換函數F看作是生成器(Generator)或者推理機。F將根據輸入的信息,結合其他知識,推理生成一系列新的命題和斷
言。模型的力量源于推導。變換函數F本身在系統構造過程中處于核心地位,M僅僅是觸發其推理過程的信息源而已。F將榨干M的最后一點剩余價值,所有根據M
能夠確定的事實將被自動實現,而大量單靠M自身的信息無法判定的命題也可以結合F內在的知識作出判斷。生成器自身的構造過程非常簡單--只要不斷向推理系
統中增加新的推理規則即可。語言內置的模板機制(template)及元編程技術(meta
programming),或者跨越語言邊界的代碼生成工具都可以看作是生成器的具體實例。(關于代碼生成和DSL http://canonical.javaeye.com/blog/275015
)
App = G<M>
7. 生成器G之所以可以被獨立實現,是因為我們可以實現相對知識與絕對知識的分離, 這也正是面向對象技術的本質所在。(面向對象之形式系統 http://canonical.javaeye.com/blog/37064
)
G<M> ==> G = {m => m.x(a,b,c);m.y();
}
8.
現實世界的不完美,就在于現實決不按照我們為其指定的理想路線前進。具體場景中總是存在著大量我們無法預知的“噪聲”,它們使得任何在“過去”確立的方程
都無法在“未來”保持持久的平衡。傳統模型驅動架構的困境就在于此。我們可以選擇將模型M和生成器G不斷復雜化,容納越來越多的偶然性,直至失去對模型整
體結構的控制力。另外一種選擇是模型在不斷膨脹,不斷提高覆蓋能力的過程中,不斷的空洞化,產生大量可插入(plugin)的接入點,最終喪失模型的推理
能力,退化成為一種編碼規范。Witrix平臺中采用的是第三種選擇:模型嵌入--模型中的多余信息被不斷清洗掉,模型通過精煉化來突出自身存在的合理
性,成為更廣泛的運行環境中的支撐骨架。(結構的自足性 http://canonical.javaeye.com/blog/482620
)
App != G0<M0> , App != G0<M1>, App = G1<M1>
9.
現在的問題是:如何基于一個已經被完美解決的重大問題,來更有效率的搞定不斷出現但又不是重復出現的小問題。現在我們所需要的不是沿著某個維度進行均勻的
切分,而必須是某種有效的降維手段。如果我們可以定義一種投影算子P,
將待解決的問題投射到已經被解決的問題域中,則剩下的補集往往可以被簡化。(主從分解而不是正交分解 http://canonical.javaeye.com/blog/196826
)
dA = App - P[App] = App - G0<M0>
10. 要實現以上微擾分析策略,前提條件是可以定義逆元,并且需要定義一種精細的粘結操作,可以將分散的擾動量極為精確的應用到基礎系統的各處。Witrix平臺的具體實現類似于某種AOP(面向切面編程)技術。(逆元:不存在的真實存在 http://canonical.javaeye.com/blog/325051
)
App = A + D + B = (A + B + C) - C + D = App0 + (-C + D) = G0<M0> + dA
11. 模型驅動并不意味著一個應用只能由唯一的一個模型來驅動,但是如果引入多個不同形式的模型,則必須為如下推理提供具體的技術路徑:
A. 將多個模型變換到共同的描述域
B. 實現多個模型的加和
C. 處理模型之間的沖突并填補模型之間的空白
在Witrix平臺中模型嵌入/組合主要依賴于文本化及編譯期運行等機制。(文本化 http://canonical.javaeye.com/blog/309395
)
App = Ga<Ma> + Gb<Mb> + dA
12.
系統的開發時刻t0和實施時刻t1一般是明確分離的,因此如果我們要建立一個包含開發與實施時刻信息的模型,則這一模型必須是含時的,多階段的。關于時
間,我們所知道的最重要的事實之一是“未來是不可預知的”。在t0時刻建立的模型如果要涵蓋t1時刻的所有變化,則必須做出大量猜測,而且t1時刻距離
t0時刻越遠,猜測的量越大,“猜測有效”這一集合的測度越小,直至為0。延遲選擇是實現含時系統控制的不二法門。
在Witrix平臺中,所有功能特性的實現都包含某種元數據描述或者定制模板,因此結合配置機制以及動態編譯技術既可實現多階段模型。例如對于一個在未來
才能確定的常量數組,我們可以定義一個Excel文件來允許實施人員錄入具體的值,然后通過動態編譯技術在編譯期解析Excel文件,并完成一系列數值映
射運算,最終將其轉化為編譯期存在的一個常量。這一過程不會引入任何額外的運行成本,也不要求任何特定的緩存機制,最終的運行結構與在未來當所有信息都在
位之后再手寫代碼沒有任何區別。(D語言與tpl之編譯期動作 http://canonical.javaeye.com/blog/57244
)
App(t1) = G(t0,t1)<M(t0,t1)> + dA(t0,t1)
13. 級列理論提供了一個演化框架,它指出孤立的模型必須被放在模型級列中被定義,被解釋。(關于級列設計理論 http://canonical.javaeye.com/blog/33824
)
M[n] = G<M[n-1]> + dMn
14.
推理的鏈條會因為任何局部反例的出現而中斷。在任意時空點上,我們能夠斷言的事實有哪些?信息越少,我們能夠確定的事實越少,能夠做出的推論也就越少。現
在流行的很多設計實質上是在破壞系統的對稱性,破壞系統大范圍的結構。比如明明ORM容器已經實現所有數據對象的統一管理,非要將其拆分為每個業務表一個
的DAO接口。很多對靈活性的追求完全沒有搞清楚信息是對不確定性的消除,而不確定性的減少意味著限制的增加,約束的增加。(From Local To
Global http://canonical.javaeye.com/blog/42874
)
組件/構件技術的宣言是生產即組裝,但是組裝有成本,有后遺癥(例如需要額外的膠水或者螺釘)。軟件的本質并不是物質,而是信息,而信息的本質是抽象的規
律。在抽象世界中最有效的生產方式是抽象的運算,運算即生產。組件式開發意味著服從現有規律,熟練應用,而原理性生產則意味著不斷創造新的規律。功能模
塊越多,維護的成本越高,是負擔,而推理機制越多,生產的成本越低,是財富。只有恢復軟件的抽象性,明確把握軟件構造過程內在的數學原理,才能真正釋放軟
件研發的生產力。(從編寫代碼到制造代碼 http://canonical.javaeye.com/blog/333167
)
注解1:很多設計原則其實是在強調軟件由人構造由人理解,軟件開發本質上是人類工程學,需要關注人類的理解力與協作能力。例如共同的建模語言減少交互成本,基于模型減少設計與實現的分離,易讀的代碼比高性能的代碼更重要,做一件事只有唯一的一種方式等。
注解2:生成系統的演繹遠比我們想象的要深刻與復雜得多。例如生命的成長可以被看作是在外界反饋下不斷調整的生成過程。
注解3:領域描述是更緊致但卻未必是更本質的表達。人類的DNA如果表達為ATGC序列完全可以拷貝到U盤中帶走,只要對DNA做少量增刪,就可以實現老
鼠到人類的變換(人類和老鼠都有大約30000條基因,其中約有80%的基因是“完全一樣的”,大約共享有99%的類似基因),但是很難認為人類所有智慧
的本質都體現在DNA中,DNA看起來更像是某種序列化保存形式而已。
注解4:模型轉換這一提法似乎是在強調模型之間的同構對應,轉換似乎總是可以雙向進行的,僅僅是實現難度限制了反向轉換而已。但是大量有用的模型變換卻是單向的,變換過程要求不斷補充新的信息。
注解5:模型驅動在很多人看來就是數據庫模型或者對象模型驅動系統界面運行,但實際上模型可以意指任意抽象知識。雖然在目前業內廣泛流行的對象范式下,所
有知識都可以表達為對象之間的關聯,但是對象關系(名詞之間的關聯關系)對運算結構的揭示是遠遠不夠充分的。很多時候所謂的領域模型僅僅是表明概念之間具
有相關性,但是如果不補充一大段文字說明,我們對于系統如何運作仍然一知半解。數學分析其實是將領域內在的意義抽空,僅余下通用的形式化符號。