契约
魔獸爭霸3中死亡騎士(Death Knight)出生時(shí)就會說一句:
The pact is sealed.
契約已簽訂。
?
看過N多童話故事和電影的小伙伴們肯定熟悉這種場景:
大反派斗不過主角,處于劣勢時(shí),就會與諸如惡魔簽訂契約,以自己的青春換取強(qiáng)大的力量,即:
? 青春 --> 惡魔 ? ? 惡魔 ?--> 力量 ?
?
我們把這個(gè)再改變一下:
惡魔 【得到】{青春} ?-> ?{力量}
看起來有點(diǎn)眼熟,這不就是function/method干的事情嗎?
function 與惡魔簽訂契約(青春) {
return 力量;
}
? ?
拿一個(gè)PHP簡單的函數(shù)來說吧,此函數(shù)是這樣的:
function getFullName($givenName, $surname) {return $givenName.' '.$surname; }? 對于調(diào)用方來說,如此調(diào)用:$fullName = getFullName($realGivenName, $realSurname);
輸入 $realGivenName 和 $realSurname 不知道是否返回結(jié)果,有結(jié)果也不知道是什么。
這里 $givenName和?$surname 兩個(gè)形參對比之下就是契約條件,而返回的值就是契約回饋。
? ? ??
每天在敲代碼,原來就是在寫各種各樣的契約,然后各個(gè)契約被各種各樣的大反派(調(diào)用方)簽訂(調(diào)用)。
?
再來看Java的一個(gè)方法
public static String getFullName(String givenName, String surname) {return givenName + " " + surname; }?
?給一個(gè)String類型 和 一個(gè)String參數(shù),返回一個(gè)String 類型的結(jié)果;
?
? ?
去跟PHP對比一下,發(fā)現(xiàn)Java的Method契約條件的限制更加嚴(yán)格了,而契約回饋的描述也更加準(zhǔn)確了。
?
即PHP函數(shù)在調(diào)用時(shí),函數(shù)形參如果不限制類型的話,可以是任意類型($givenName 可以是一個(gè)int,也可以是array,甚至是一個(gè)resource類型,或者干脆是null),
基于動態(tài)語言的特點(diǎn),甚至還可以傳多于/少于(少于的話PHP會報(bào)Warning級別的錯(cuò)誤)function規(guī)定的參數(shù)數(shù)目進(jìn)去!
?
所以在上面這種實(shí)現(xiàn)在遇到特殊情況下,就會出現(xiàn)意想不到的結(jié)果,因此具體實(shí)現(xiàn)要對變量類型、值做各種判斷;
而Java在實(shí)現(xiàn)內(nèi)則不需要做類型判斷,只需要處理空的情況即可;
?
對于return 的結(jié)果來說,PHP function實(shí)現(xiàn)可以返回 null、int,array,resource... 又是不限制類型和值!契約回饋又是模糊的描述……
?
所以,PHP function/method 契約是模糊的,契約回饋的描述也是模糊,而Java則更加強(qiáng)調(diào)契約發(fā)起方和契約執(zhí)行方的明確的責(zé)任;
?
如此這般,PHP 一個(gè)function/method 實(shí)現(xiàn)(契約執(zhí)行方)就頭大了,調(diào)用方(契約發(fā)起方)傳過來的參數(shù)(契約條件)很有可能存在
意想不到的情況,于是就需要在實(shí)現(xiàn)內(nèi)加類型判斷, 處理空或者其他情況。調(diào)用方也不知道實(shí)現(xiàn)是否真的能達(dá)成契約描述(function/method名稱,注釋等)
那樣的美好的結(jié)果,調(diào)用方又得對實(shí)現(xiàn)返回進(jìn)行判斷。
?
而Java則只是對象參數(shù)需要處理null的情況,因?yàn)橛幸徊骄幾g的過程,類型則不需要費(fèi)心。即在通過編譯后,契約雙方的基本條件和回饋描述被保證了。
PS:這么一說,編譯器(Compiler)聽起來就像是一個(gè)公證人似的。
?
總的來說,PHP因?yàn)椴槐卦诼暶髯兞炕蛘咧贫ǚ椒ê灻麜r(shí)聲明類型,所以是弱契約。 ? ?
?
弱契約的好處是顯而易見的:
調(diào)用方的責(zé)任限制變少,執(zhí)行方(實(shí)現(xiàn))的責(zé)任 加重(即兼容 各種參數(shù)情況),那么只需要一個(gè)契約執(zhí)行方,就可以滿足多種調(diào)用方的情況。
即一個(gè)function/method實(shí)現(xiàn),調(diào)用方多種情況來調(diào)用都是沒問題的;
我們也可以把這種實(shí)現(xiàn)成為健壯的實(shí)現(xiàn);
?
Java則是強(qiáng)契約,好處不必多說,但是劣勢對比弱契約也是很明顯,調(diào)用方參數(shù)若是出現(xiàn)了另外一種類型或者參數(shù)變多/變少,則不得不重載(Overload),
如果業(yè)務(wù)復(fù)雜起來,重載方法寫起來簡直是惡心;
?
?
說道這里泛型橫空出世,我們可以理解泛型其實(shí)就是在強(qiáng)契約和弱契約之間的一種折中,即Method契約不再死板地限制某個(gè)具體類型,也不死板地規(guī)定
返回某個(gè)具體類型,而是規(guī)定為某一系列的類型,即在強(qiáng)契約的上弱化了一些,將類型限制放寬。
?
?
使用了泛型的方法,則可以滿足調(diào)用方的某一系列的參數(shù)類型情況,讓我們少些重載方法,減少了代碼量 :)
?
?
return ;
?
轉(zhuǎn)載于:https://www.cnblogs.com/Joynic/p/6828590.html
總結(jié)
- 上一篇: 保留小数点后两位小数
- 下一篇: 图解Javascript——作用域、作用