我遇見的大多數(shù)碼農(nóng)都讀過“四人幫”的那本《設(shè)計(jì)模式》。任何稍有自尊心的碼農(nóng)都會說這本書和語言無關(guān),因此無論你用什么編程語言,當(dāng)中提到的那些模式大體上適用于所有軟件工程。聽起來很厲害,然而事實(shí)卻不是這樣。
函數(shù)式語言的表達(dá)能力很強(qiáng)。用這種語言編程的時候基本不需要設(shè)計(jì)模式,因?yàn)檫@種語言層次已經(jīng)足夠高,使得使用者可以以概念編程,從而完全不需要設(shè)計(jì)模式了。以適配器模式為例(有人知道這個模式和外觀模式有什么區(qū)別嗎?怎么覺得有人為了出版合同的要求而硬生生湊頁數(shù)?)(譯者:您不愧是高級黑?。?。對于一個支持currying技術(shù)的語言來說,這個模式就是多余的。
在Jaya中最有名的適配器模式就是在其“默認(rèn)”抽象單元中的應(yīng)用:類。在函數(shù)式語言中這種模式其實(shí)就是函數(shù)。在這個模式中,一個接口被轉(zhuǎn)換成另外一個接口,讓不同的用戶代碼調(diào)用。接下來就有一個適配器模式的例子:
int pow(int i, int j);
int square(int i)
{
return pow(i, 2);
}
上面的代碼中square函數(shù)計(jì)算一個整數(shù)的平方,這個函數(shù)的接口被轉(zhuǎn)換成計(jì)算一個整數(shù)的任意整數(shù)次冪。在學(xué)術(shù)圈里這種簡單的技術(shù)就被叫做currying(因?yàn)檫壿媽W(xué)家哈斯凱爾·加里用其數(shù)學(xué)技巧將這種技術(shù)描述出來,于是就以他的名字來命名了)。在一個FP語言中函數(shù)(而不是類)被作為參數(shù)進(jìn)行傳遞,currying常常用于轉(zhuǎn)化一個函數(shù)的接口以便于其他代碼調(diào)用。函數(shù)的接口就是它的參數(shù),于是currying通常用于減少函數(shù)參數(shù)的數(shù)量(見前例)。
函數(shù)式語言生來就支持這一技術(shù),于是沒有必要為某個函數(shù)手工創(chuàng)建另外一個函數(shù)去包裝并轉(zhuǎn)換它的接口,這些函數(shù)式語言已經(jīng)為你做好了。我們繼續(xù)拓展Java來支持這一功能。
square = int pow(int i, 2);
上面的語句實(shí)現(xiàn)了一個平方計(jì)算函數(shù),它只需要一個參數(shù)。它會繼而調(diào)用pow函數(shù)并且把第二個參數(shù)置為2。編譯過后將生成以下Java代碼:
class square_function_t {
int square(int i) {
return pow(i, 2);
}
}
square_function_t square = new square_function_t();
從上面的例子可以看到,很簡單的,函數(shù)pow的封裝函數(shù)就創(chuàng)建出來了。在FP語言中currying就這么簡單:一種可以快速且簡單的實(shí)現(xiàn)函數(shù)封裝的捷徑。我們可以更專注于自己的設(shè)計(jì),編譯器則會為你編寫正確的代碼!什么時候使用currying呢?很簡單,當(dāng)你想要用適配器模式(或是封裝函數(shù))的時候,就是用currying的時候。
更多建議: