[導(dǎo)入]唯一性與自洽性
Posted on 2006-04-23 16:39 canonical 閱讀(1694) 評(píng)論(0) 編輯 收藏 所屬分類: 設(shè)計(jì)理論
http://xp.c2.com/OnceAndOnlyOnce.html
http://c2.com/cgi/wiki?DontRepeatYourself
???? OAOO(Once And Only Once)是我們?cè)谲浖_(kāi)發(fā)中需要關(guān)注的基本原則之一. 唯一性當(dāng)然是一個(gè)值得追求的目標(biāo). 從正交分解的角度上說(shuō),系統(tǒng)可以由少數(shù)的正交基通過(guò)組合構(gòu)造出來(lái)。尤其在分析階段,我們需要牢牢把握住系統(tǒng)內(nèi)核的幾個(gè)變化維度。但是這并不意味著我們最終能夠做到每種可以想見(jiàn)的軟件元素都是唯一的,也不意味著保持唯一性永遠(yuǎn)都是最好的。
???? 唯一性在軟件中最直接的體現(xiàn)就是代碼的重用(reuse), 除了實(shí)現(xiàn)起來(lái)節(jié)省了工作量之外,代碼重用的另一個(gè)作用在于維護(hù)了系統(tǒng)中概念的唯一性,或者更廣泛的說(shuō),它維護(hù)了系統(tǒng)中知識(shí)的唯一性。例如,如果我們經(jīng)常用到圓周率Pi,我們可以選擇在各處都直接寫3.1415926, 也可以選擇定義一個(gè)系統(tǒng)常數(shù)PI, 在使用的時(shí)候引用這個(gè)常數(shù),保持關(guān)于PI值的知識(shí)的唯一性。其實(shí)只要各處的PI值是相同的,甚至只要是在誤差范圍內(nèi)相互匹配的(例如有些地方用3.14, 有些地方用3.1415926),程序就可以正確無(wú)誤的運(yùn)行,這樣就達(dá)到了我們開(kāi)發(fā)程序的目的,并不需要什么常數(shù)定義。只是為了保證這種知識(shí)的一致性,定義一個(gè)常數(shù)無(wú)疑是最簡(jiǎn)單直接的一種方法。從理論上說(shuō),我們實(shí)際需要的只是知識(shí)在軟件中能夠得到一致的表達(dá),或者更加抽象一些,我們所需要的只是知識(shí)的自洽性,而唯一性無(wú)疑是維持自洽性的一種廉價(jià)方法。特別是在一個(gè)不斷演化的系統(tǒng)中,保持形式上的唯一性可能是實(shí)現(xiàn)自洽性的唯一可行的方法。
???? 但是, 我們需要認(rèn)識(shí)到知識(shí)的一致性與代碼的唯一性并不是等同的,例如同樣是釋放資源的函數(shù), 在不同的應(yīng)用情形下我們可能將其命名為close, 也可能是destroy, 或者是dispose, 如果我們使用一個(gè)接口IDisposable.dispose(), 則引入了一種形式上的唯一性要求. 在使用reflection的情況下, 我們可以放松要求, 不要求對(duì)象實(shí)現(xiàn)特定的接口, 只要提供指定的函數(shù)名(例如dispose)即可. 我們也可以更加寬容, 通過(guò)外部描述性數(shù)據(jù)指定函數(shù)的用途, 只要求概念上的一致性, 例如spring中通過(guò)destroy-method屬性指定對(duì)象資源釋放函數(shù). 沒(méi)有語(yǔ)言級(jí)別的形式唯一性, 我們就無(wú)法依賴于編譯器來(lái)維護(hù)其隱含的知識(shí)的一致性, 此時(shí)我們所能使用的通用方法就只有測(cè)試(test)了. 實(shí)際上, 很多知識(shí)上的自洽性要求都無(wú)法在程序中直接得到表達(dá), 而只能通過(guò)一個(gè)構(gòu)造的測(cè)試網(wǎng)絡(luò)來(lái)進(jìn)行驗(yàn)證.
???? 正如排他鎖(exclusive lock)是實(shí)現(xiàn)transaction的一種強(qiáng)形式一樣, 唯一性也是自洽性的一種強(qiáng)形式。在保持了唯一性的情況下,當(dāng)然不可能出現(xiàn)沖突的情況,也就自然的維持了系統(tǒng)的自洽性。但是,很多時(shí)候概念的多樣性也是我們不得不考慮的內(nèi)容。在C語(yǔ)言中, memmove函數(shù)的功能包括memcpy的功能,到底要不要取消memcpy以避免無(wú)謂的錯(cuò)誤可不是一件容易決定的事情. 在數(shù)學(xué)上,同一個(gè)定理可能存在著多種非平凡(non-trivial)的等價(jià)表述形式, 從表面上看,它們可以是完全不相關(guān)的,但是原理上是等價(jià)的. 而不同的表述往往適用于不同的應(yīng)用情形. 同樣的,在軟件系統(tǒng)中,It is ok to have more than one representation of a piece of knowledge provided an effective mechanism for ensuring consistency between them is engaged. 在軟件設(shè)計(jì)中, 引入中間層是在控制內(nèi)在統(tǒng)一性的同時(shí)獲得豐富的外在表現(xiàn)的一種重要方式. 在CORBA中idl編譯器將idl文件翻譯成不同程序語(yǔ)言的版本, 我們?cè)诔绦蛑惺褂玫氖翘囟ǔ绦蛘Z(yǔ)言的版本而不是直接的idl接口文件, 這些版本之間的自洽性是通過(guò)idl編譯器來(lái)保證的. idl編譯器所做的只是一對(duì)一的翻譯工作, 它本身并沒(méi)有提供額外的知識(shí), 而它所生成的各個(gè)程序語(yǔ)言版本所表達(dá)的知識(shí)也是相同的. 可以想見(jiàn), 一種更加復(fù)雜的,甚至是具備一定推理能力的引擎(engine)可以基于元知識(shí)進(jìn)行更加復(fù)雜的變換工作, 并可以融合其他外部的知識(shí), 最終輸出一系列自洽的表現(xiàn)結(jié)構(gòu).例如, 我們可以根據(jù)一個(gè)描述文件生成所有CRUD(Create Read Update Delete)操作的程序代碼和界面代碼. 這些生成的文件中可能存在著重復(fù)的代碼,可能重復(fù)的表達(dá)了某個(gè)知識(shí), 例如界面布局等, 但是它們之間通過(guò)引擎隱蔽的存在著穩(wěn)固的聯(lián)系
http://c2.com/cgi/wiki?DontRepeatYourself
???? OAOO(Once And Only Once)是我們?cè)谲浖_(kāi)發(fā)中需要關(guān)注的基本原則之一. 唯一性當(dāng)然是一個(gè)值得追求的目標(biāo). 從正交分解的角度上說(shuō),系統(tǒng)可以由少數(shù)的正交基通過(guò)組合構(gòu)造出來(lái)。尤其在分析階段,我們需要牢牢把握住系統(tǒng)內(nèi)核的幾個(gè)變化維度。但是這并不意味著我們最終能夠做到每種可以想見(jiàn)的軟件元素都是唯一的,也不意味著保持唯一性永遠(yuǎn)都是最好的。
???? 唯一性在軟件中最直接的體現(xiàn)就是代碼的重用(reuse), 除了實(shí)現(xiàn)起來(lái)節(jié)省了工作量之外,代碼重用的另一個(gè)作用在于維護(hù)了系統(tǒng)中概念的唯一性,或者更廣泛的說(shuō),它維護(hù)了系統(tǒng)中知識(shí)的唯一性。例如,如果我們經(jīng)常用到圓周率Pi,我們可以選擇在各處都直接寫3.1415926, 也可以選擇定義一個(gè)系統(tǒng)常數(shù)PI, 在使用的時(shí)候引用這個(gè)常數(shù),保持關(guān)于PI值的知識(shí)的唯一性。其實(shí)只要各處的PI值是相同的,甚至只要是在誤差范圍內(nèi)相互匹配的(例如有些地方用3.14, 有些地方用3.1415926),程序就可以正確無(wú)誤的運(yùn)行,這樣就達(dá)到了我們開(kāi)發(fā)程序的目的,并不需要什么常數(shù)定義。只是為了保證這種知識(shí)的一致性,定義一個(gè)常數(shù)無(wú)疑是最簡(jiǎn)單直接的一種方法。從理論上說(shuō),我們實(shí)際需要的只是知識(shí)在軟件中能夠得到一致的表達(dá),或者更加抽象一些,我們所需要的只是知識(shí)的自洽性,而唯一性無(wú)疑是維持自洽性的一種廉價(jià)方法。特別是在一個(gè)不斷演化的系統(tǒng)中,保持形式上的唯一性可能是實(shí)現(xiàn)自洽性的唯一可行的方法。
???? 但是, 我們需要認(rèn)識(shí)到知識(shí)的一致性與代碼的唯一性并不是等同的,例如同樣是釋放資源的函數(shù), 在不同的應(yīng)用情形下我們可能將其命名為close, 也可能是destroy, 或者是dispose, 如果我們使用一個(gè)接口IDisposable.dispose(), 則引入了一種形式上的唯一性要求. 在使用reflection的情況下, 我們可以放松要求, 不要求對(duì)象實(shí)現(xiàn)特定的接口, 只要提供指定的函數(shù)名(例如dispose)即可. 我們也可以更加寬容, 通過(guò)外部描述性數(shù)據(jù)指定函數(shù)的用途, 只要求概念上的一致性, 例如spring中通過(guò)destroy-method屬性指定對(duì)象資源釋放函數(shù). 沒(méi)有語(yǔ)言級(jí)別的形式唯一性, 我們就無(wú)法依賴于編譯器來(lái)維護(hù)其隱含的知識(shí)的一致性, 此時(shí)我們所能使用的通用方法就只有測(cè)試(test)了. 實(shí)際上, 很多知識(shí)上的自洽性要求都無(wú)法在程序中直接得到表達(dá), 而只能通過(guò)一個(gè)構(gòu)造的測(cè)試網(wǎng)絡(luò)來(lái)進(jìn)行驗(yàn)證.
???? 正如排他鎖(exclusive lock)是實(shí)現(xiàn)transaction的一種強(qiáng)形式一樣, 唯一性也是自洽性的一種強(qiáng)形式。在保持了唯一性的情況下,當(dāng)然不可能出現(xiàn)沖突的情況,也就自然的維持了系統(tǒng)的自洽性。但是,很多時(shí)候概念的多樣性也是我們不得不考慮的內(nèi)容。在C語(yǔ)言中, memmove函數(shù)的功能包括memcpy的功能,到底要不要取消memcpy以避免無(wú)謂的錯(cuò)誤可不是一件容易決定的事情. 在數(shù)學(xué)上,同一個(gè)定理可能存在著多種非平凡(non-trivial)的等價(jià)表述形式, 從表面上看,它們可以是完全不相關(guān)的,但是原理上是等價(jià)的. 而不同的表述往往適用于不同的應(yīng)用情形. 同樣的,在軟件系統(tǒng)中,It is ok to have more than one representation of a piece of knowledge provided an effective mechanism for ensuring consistency between them is engaged. 在軟件設(shè)計(jì)中, 引入中間層是在控制內(nèi)在統(tǒng)一性的同時(shí)獲得豐富的外在表現(xiàn)的一種重要方式. 在CORBA中idl編譯器將idl文件翻譯成不同程序語(yǔ)言的版本, 我們?cè)诔绦蛑惺褂玫氖翘囟ǔ绦蛘Z(yǔ)言的版本而不是直接的idl接口文件, 這些版本之間的自洽性是通過(guò)idl編譯器來(lái)保證的. idl編譯器所做的只是一對(duì)一的翻譯工作, 它本身并沒(méi)有提供額外的知識(shí), 而它所生成的各個(gè)程序語(yǔ)言版本所表達(dá)的知識(shí)也是相同的. 可以想見(jiàn), 一種更加復(fù)雜的,甚至是具備一定推理能力的引擎(engine)可以基于元知識(shí)進(jìn)行更加復(fù)雜的變換工作, 并可以融合其他外部的知識(shí), 最終輸出一系列自洽的表現(xiàn)結(jié)構(gòu).例如, 我們可以根據(jù)一個(gè)描述文件生成所有CRUD(Create Read Update Delete)操作的程序代碼和界面代碼. 這些生成的文件中可能存在著重復(fù)的代碼,可能重復(fù)的表達(dá)了某個(gè)知識(shí), 例如界面布局等, 但是它們之間通過(guò)引擎隱蔽的存在著穩(wěn)固的聯(lián)系