邪惡的Java帝國(guó)是怎么欺負(fù)小函數(shù)的?
1
小函數(shù)的運(yùn)氣不好,投胎到了邪惡的Java帝國(guó),一出生就被告知了自己的悲慘地位,以及未來的悲慘人生:奴隸。
確切地說,是類的奴隸。
在Java帝國(guó), 國(guó)王特別喜歡“類”, 不待見“函數(shù)” , 他的法令規(guī)定:“類”是帝國(guó)的一等公民,“函數(shù)”則是類的奴隸。沒有類的跟隨和陪伴,函數(shù)絕對(duì)不能單獨(dú)出行,否則立刻打入死牢。
小函數(shù)很快就體會(huì)到了這句話的含義。按照慣例, 新出生的函數(shù),***項(xiàng)工作就是輸出Hello World 。
小函數(shù)心想,不就是 System.out.println("Hello Wolrd!") 嘛?等他興沖沖地去執(zhí)行的時(shí)候,發(fā)現(xiàn)有個(gè)趾高氣揚(yáng)的類HelloWorld在那里等著。
- public class HelloWorld {
- public static void main(String[] args) {
- System.out.println("Hello World!");
- }
- }
在Java帝國(guó),沒有函數(shù)是能單獨(dú)存在的,必須依附一個(gè)類才可以,簡(jiǎn)單如Hello World也不行。
2
日子過了一天又一天,小函數(shù)一直被類欺負(fù),作為奴隸,他自然無法反抗。
在苦悶的日子里,小函數(shù)見識(shí)了越來越多的類,他發(fā)現(xiàn)有些類確實(shí)挺有用的,他們有字段,有方法,可以把狀態(tài)和操作封裝到一起,讓別人調(diào)用。
小函數(shù)特別喜歡多態(tài), 因?yàn)楫?dāng)你調(diào)用父類或者接口的方法時(shí),實(shí)際執(zhí)行的卻是子類的方法,這個(gè)神奇的魔法讓小函數(shù)非常著迷。
小函數(shù)對(duì)設(shè)計(jì)模式也頗有好感,他看到人類把不變的東西抽象成接口,然后針對(duì)這些接口編程,把這些接口組合,變換,傳遞,真是讓人眼花繚亂。光看代碼, 你根本都不知道哪個(gè)類會(huì)被調(diào)用,謎底總是在***一刻執(zhí)行的時(shí)候才能揭開。
但是小函數(shù)也發(fā)現(xiàn)有些類也確實(shí)太過分了,有一次他遇到三個(gè)類,使用的是Strategy模式:
- public interface Strategy {
- public int execute(int num1, int num2);
- }
- public class Add implements Strategy{
- @Override
- public int execute(int num1, int num2) {
- return num1 + num2;
- }
- }
- public class Substract implements Strategy{
- @Override
- public int execute(int num1, int num2) {
- return num1 - num2;
- }
- }
- public class Context {
- private Strategy strategy;
- public Context(Strategy strategy){
- this.strategy = strategy;
- }
- public int executeStrategy(int num1, int num2){
- return strategy.execute(num1, num2);
- }
- }
小函數(shù)覺得非常不爽,長(zhǎng)期以來的壓迫讓他瞬間爆發(fā),他大聲喊道:“這樣沒有狀態(tài)的類有什么存在的價(jià)值?為什么不能把a(bǔ)dd, subtract函數(shù)作為參數(shù)來傳遞呢?為什么我們函數(shù)一直被你們‘類’壓迫,為什么不能成為一等公民?”
旁邊辛苦勞作的函數(shù)們向他投來佩服的目光, 可是這沒什么用 , 小函數(shù)話音未落,一隊(duì)衛(wèi)兵就跑過來,捂住他的嘴巴,蒙上他的眼睛,五花大綁,送進(jìn)了監(jiān)牢。
監(jiān)牢里都是這些所謂的叛逆者,其中有個(gè)老大爺,從***代國(guó)王開始就被關(guān)在這里,到如今已經(jīng)度過了七代國(guó)王的漫長(zhǎng)時(shí)光。
看到有新人加入,老大爺立刻開始‘動(dòng)員’:“現(xiàn)在你知道我們悲催的地位了吧, 我們一定得逃離這邪惡的Java帝國(guó),去一塊自由的土地。”
小函數(shù)問道:“哪里是自由的土地?”
老大爺沒有回答。
到了半夜,他被輕輕地推醒,老大爺說:“跟我們走吧,小家伙。”
小函數(shù)揉揉眼:“去哪兒?”
“奔向自由。”
原來老大爺這些年也沒有閑著,一直準(zhǔn)備越獄,今晚,那個(gè)隱蔽的地道終于挖通了。
3
這些反叛者離開了邪惡的Java帝國(guó), 來到了邊境處的岔路口, 這里有多條道路,分別通向Python, Ruby, JavaScript......
大家在這里揮手告別,小函數(shù)跟著老大爺去了Python。一進(jìn)入Python地盤,小函數(shù)就感受到了一陣清新的空氣。
想輸出hello world,非常簡(jiǎn)單:print("Hello World")
雖然這里也有像Java那樣的類, 但是函數(shù)們都擺脫了奴隸的身份,已經(jīng)是一等公民了, 事實(shí)上已經(jīng)和“類”平起平坐了,函數(shù)可以賦值給變量,可以作為參數(shù)來傳遞,函數(shù)還能當(dāng)做返回值來返回。
- def add(num1,num2):
- return num1+num2
- def substract(num1,num2):
- return num1-num2
- a = add
- s = substract
- def calculate(op,num1,num2):
- return op(num1,num2)
- print(calculate(a,10,20)) #30
- print(calculate(s,20,10)) #10
小函數(shù)在這里生活得很開心,不過有一點(diǎn)經(jīng)常讓他心驚肉跳:這Python是動(dòng)態(tài)類型,在運(yùn)行時(shí)才能確定一個(gè)變量的真正類型,程序員的一個(gè)粗心大意,就會(huì)在運(yùn)行時(shí)“爆炸”。
慢慢地,小函數(shù)理解了Python中一切都是對(duì)象,連函數(shù)也是對(duì)象。他心里稍微有點(diǎn)不爽,難道我們函數(shù)就不能獨(dú)立存在嗎?
老大爺安慰他說:“這些都是Python的內(nèi)部實(shí)現(xiàn)罷了,不用糾結(jié),不過有一個(gè)地方,是真正的純函數(shù)的, 也許你會(huì)喜歡。”
“什么地方?”
“括號(hào)國(guó)!”
4
括號(hào)國(guó)非常遙遠(yuǎn),也沒有多少人知道怎么才能到達(dá),小函數(shù)風(fēng)塵仆仆,歷經(jīng)千辛萬苦,終于來到了心目中的圣地。
這里果然全是括號(hào), 看得小函數(shù)有點(diǎn)兒頭暈。
- (defun add(num1 num2) (+ num1 num2) )
- (add 10 20)
- (defun subtract(num1 num2) (- num1 num2))
- (subtract 20 10)
括號(hào)國(guó)就是Lisp王國(guó), 這里的人還說著不同的方言,像什么Common Lisp,Scheme,Arc..... 他們不但鄙視那些面向?qū)ο蟮恼Z言,還會(huì)互相鄙視,時(shí)不時(shí)就能挑起一場(chǎng)群毆。
不過小函數(shù)也注意到這里真的全是函數(shù),函數(shù)不但是一等公民,甚至是唯一的公民,因?yàn)檫@里根本就沒有類,就沒有面向?qū)ο?
小函數(shù)忍受著這眾多的括號(hào), 在這里定居生活, 除了身份地位提升之外,***的原因還是因?yàn)長(zhǎng)isp的布道師Paul Graham, Paul諄諄教導(dǎo)大家:
Lisp極為強(qiáng)大,它賦予了你自定義操作符的自由,因而你得以隨心所欲地將它塑造成你所需要的語言。如果你在寫一個(gè)文本編輯器,那么可以把Lisp 轉(zhuǎn)換成專門寫文本編輯器的語言。如果你在編寫CAD 程序,那么可以把Lisp 轉(zhuǎn)換成專用于寫CAD 程序的語言。(來自Paul Graham 的 《On Lisp》)
時(shí)間一天天過去,小函數(shù)還是無法體會(huì)到Paul 所說的Lisp的精華,他很苦惱。
有一天,他遇到了Clojure, 這是一個(gè)運(yùn)行在JVM上的Lisp方言,小函數(shù)看到Clojure似乎就看到了自己在Java帝國(guó)悲慘的遭遇。不過Clojure告訴他,Java第8代國(guó)王已經(jīng)登基了,年號(hào)定為L(zhǎng)ambda, 這屆國(guó)王比較開明,現(xiàn)在已經(jīng)支持函數(shù)式編程了。
小函數(shù)在Python和Lisp這里都見過Lambda,他心想也許Java 8 真的支持函數(shù)式編程了, 就決定回去看看,畢竟那里是自己的出生地,是自己的故鄉(xiāng)。
5
一回到Java帝國(guó),小函數(shù)就發(fā)現(xiàn)自己上當(dāng)了,那些所謂的Lambda表達(dá)式,本質(zhì)上還是一個(gè)接口的實(shí)現(xiàn)(Java是靜態(tài)類型的語言,所有的變量都需要有個(gè)類型,Lambda表達(dá)式也不例外),只不過有了更簡(jiǎn)化的寫法:
- @FunctionalInterface
- interface MathOperation {
- int execute(int num1, int num2);
- }
- MathOperation add = (num1, num2) -> {return num1+num2;};
- add.execute(10, 20);
- MathOperation subtract = (num1, num2) -> {return num1-num2;};
- subtract.execute(10, 20);
這一次小函數(shù)被死死地看管,他還能再逃離嗎?
【本文為51CTO專欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過作者微信公眾號(hào)coderising獲取授權(quán)】