十年之后再看“面向对象”
一起幫里有人問“面向?qū)ο蟆钡膯栴}。但我創(chuàng)建“一起幫”的目的是幫人解決“具體的”“實(shí)務(wù)性的”問題,“面向?qū)ο蟆碧^于抽象,所以沒批準(zhǔn)發(fā)布。后來在QQ群里討論,看他們七嘴八舌鬧得慌,突然有一種“多情應(yīng)笑我,早生華發(fā)”的蕭瑟之感。
一轉(zhuǎn)眼,我學(xué)編程都已經(jīng)十年了。
十年之前,“面向?qū)ο蟆被鸬靡凰俊?/p>
十年之后,“面向?qū)ο蟆?#xff0c;沒想到,還是這樣云里霧里……
?
回頭想想,之所以云里霧里,我認(rèn)為一個很大的原因:我們把“面向?qū)ο蟆鄙裨捔?/strong>。
我今天,就想損一點(diǎn)兒,來把“面向?qū)ο蟆崩律駢伞(∩_∩)O~
?
我現(xiàn)在都還記得,那時候炫耀自己的項(xiàng)目,“純面向?qū)ο箝_發(fā)”……一個“純”字,頓時逼格滿滿。現(xiàn)在想來,那時候說話確實(shí)不走腦子。“純面向?qū)ο蟆?#xff0c;還有“不純”的么?“不純”的是什么?是雜質(zhì),是渣滓?是那些if...else...,是不是應(yīng)該被剔除?問題是,你剔除了if...else ...,你項(xiàng)目里還能剩下些什么?
不知道大家以前有沒有想過這個問題?
我覺得這是一個好問題。“純面向?qū)ο蟆边@種說法背后折射出來的,就是把“面向?qū)ο蟆焙汀懊嫦蜻^程”對立化,從而把“面向?qū)ο蟆比藶榘胃呷藶樯裨挕?/p>
?
因?yàn)樽罱鼊恿俗雠嘤?xùn)來推廣一起幫的念頭,我會這樣來思考這個問題:假如我是老師,我會怎么和同學(xué)們講解“面向?qū)ο蟆?#xff1f;“繼承”“封裝”……No,No,No,那是以后的事。事實(shí)上,很長一段時間,我就是被這些東西搞暈了,而沒能觸及到“面向?qū)ο蟆钡谋举|(zhì)。
?
我覺得,一步一步由淺入深的理解“面向?qū)ο蟆?#xff0c;正確的姿勢應(yīng)該是這樣的:
首先,同學(xué)們已經(jīng)理解了方法/函數(shù),明白為了代碼的重用,我們需要一個又一個的函數(shù)。
那么,假設(shè)我們有一個項(xiàng)目,十萬行代碼(這其實(shí)就是微型項(xiàng)目),按一個函數(shù)平均50行計(jì)算,就會有2000個函數(shù)!好,問題來了,2000個函數(shù)啊,別說你記住了,你先想想,你咋命名?呵呵。
所以,一定得想辦法,把他們“歸類”(大家注意這個“類”字):這50個函數(shù),都是干這事兒的;那50個函數(shù),都是干那事兒的……分門別類之后,2000個函數(shù),50個類,這樣,是不是有條理得多,清晰得多了呢?然后,調(diào)用一個方法的時候,先找到類,再找這個類下面的函數(shù),是不是更流暢一些?比如:Blog.Publish(),Comment.Publish(),Blog.Agree(),Comment.Agree()……你看,也不用擔(dān)心“重名”了。
這才是對“類”最基本最入門的理解——然而,很多同學(xué),恰恰是缺乏這種最基本的理解,或者理解得不夠深入,就直接奔那些“高大上”的概念去了。從而,在開發(fā)過程中整出很多莫名其妙的“幺蛾子”來。
可能有些同學(xué)不服氣,“我怎么就理解得不夠深入啦”,“這還需要這么深入理解”?或者,還有一些同學(xué),要教育教育我,“你這個理解太初淺了”,“引入‘面向?qū)ο蟆?#xff0c;是為了‘重用’‘抽象’”,“來來來,我給你講講‘設(shè)計(jì)模式’,高級貨!”……
這就是問題所在!有些同學(xué),用了一堆的“高級貨”,把本來復(fù)雜的程序搞得“更復(fù)雜”了。于是,有了所謂“濫用”,“濫用繼承”“濫用設(shè)計(jì)模式”“濫用……”我想,有過一定開發(fā)經(jīng)驗(yàn)的同學(xué)一定聽說過甚至見識過這種“濫用”的,夠酸爽吧?哈哈。那么,怎么才算“濫用”,怎么才能避免“濫用”?
其核心就在于理解一點(diǎn):面向?qū)ο?#xff08;其實(shí)包括所有針對“企業(yè)級應(yīng)用”開發(fā)的思路策略),核心目的都是“降低系統(tǒng)的復(fù)雜度”,注意:降低,降低,降低,而不是“增加”系統(tǒng)的復(fù)雜度。業(yè)務(wù)需求本身已經(jīng)夠復(fù)雜了,就不要再給代碼里“添亂”了。
請注意,這里的“復(fù)雜”,通常指的是“繁多”“雜亂”“無序”,人腦難以應(yīng)付。怎么解決這個問題呢?無它,歸類而已。
?
好了,回到“面向?qū)ο蟆?#xff0c;我們已經(jīng)把函數(shù)進(jìn)行了歸類,感覺上舒服多了。然而,當(dāng)代碼量進(jìn)一步膨脹,達(dá)到100萬級的時候,就是類,也有500個了,我們的腦子還是不夠用了。這時候,我們就會問:可不可以把這些類再進(jìn)一步的歸類呢?
當(dāng)然可以,于是就有了“繼承”;在“繼承”的基礎(chǔ)上,又有了“多態(tài)”;有了“多態(tài)”,就有了“設(shè)計(jì)模式”……
這些東西這篇博客我都不想講,一篇博客也講不了——太龐大了。
那我想講的是什么?
是順序,是目的。
?
是先有方法函數(shù),然后才有類;是有了類,然后才有了繼承……
或者,更準(zhǔn)確的說:是先有了一堆一堆多得讓人抓狂的方法函數(shù),才有了類;是先有了一堆一堆多得讓人抓狂的類,才有了繼承……
更本質(zhì)的說法:是先有了問題,然后才有解決方案。
而我們使用各種工具方法的目的,是為了解決問題。
?
這十年的編程生涯,我其實(shí)走得比較順。(比TM的搞家裝強(qiáng)太多了!)如果一定要說“走了什么彎路”,也就是在“面向?qū)ο蟆?#xff08;以及衍生出來的種種,譬如“設(shè)計(jì)模式”)上面。
我想,最大的問題就在于:一開始,“面向?qū)ο蟆边@玩意兒就是被“灌”進(jìn)腦子里的,而且你還被不停的灌輸它好很好灰常好——但究竟怎么個好法,卻很少有人能說得清楚。所以一直暈乎暈乎的,不明覺厲。而且你會自然而然的產(chǎn)生一種心理:面向?qū)ο蠛?#xff0c;沒有面向?qū)ο缶褪遣缓玫摹?/p>
這當(dāng)然是不對的。
你可以把“面向?qū)ο蟆碑?dāng)做機(jī)關(guān)槍,機(jī)關(guān)槍火力猛射程遠(yuǎn),但這并不是說機(jī)關(guān)槍就是最好的,手槍步槍狙擊槍都是渣,而是各有各的用途。
這本來很好理解,然后,當(dāng)你手里有了一把機(jī)關(guān)槍,而你又狂熱的喜歡這把機(jī)關(guān)槍的時候,事情就變味了。你會說,機(jī)關(guān)槍一樣可以干手槍的活,
- 我用機(jī)關(guān)槍比你用手槍還好使,
- 你覺得不好用,那是你不會用,
- 不信你看著……
這就走上邪路了。
?
機(jī)關(guān)槍這個例子,如果現(xiàn)實(shí)生活中真有這樣的人,你一定覺得他是瘋子。
但在IT圈里,其實(shí)到處都是這種瘋子。隔三差五的各種語言撕逼、框架撕逼、陣營撕逼,本質(zhì)上,不就這么回事么?
?
矯枉過正的說,“面向?qū)ο蟆?#xff0c;或者“面向?qū)ο蠓邸眰?#xff0c;確實(shí)有走上邪路的傾向。
如果說你確實(shí)能把“機(jī)關(guān)槍”玩出“狙擊槍”的效果,那邪也邪得有個性,溜得飛起!問題是絕大多數(shù)人,沒有這種本事,邯鄲學(xué)步,就有些尷尬了。
?
我舉一個例子:
現(xiàn)在有兩個類,一個用戶類(User),一個博客類(Blog),現(xiàn)在有一個發(fā)布博客的方法(Publish)。
那么,“發(fā)布博客”這個方法,究竟是應(yīng)該放在用戶的類里面,還是博客的類里面?即:究竟是User.Publish(Blog)呢,還是Blog.Publish()?
以下為思考時間:
滴答……
滴答,滴答……
滴答,滴答,滴答……
如果按照“萬物皆對象”,“對象映射實(shí)體”,“方法就是對象的行為”……之類的格言來套的話,當(dāng)然應(yīng)該是User.Publish(Blog),你看,用戶 發(fā)布 博客,一一對應(yīng)啊!美滴很~~就像我們老師教的那樣,名詞做對象,動詞做方法……
但有過一定開發(fā)經(jīng)驗(yàn)的同學(xué),就知道應(yīng)該是Blog.Publish(),但為什么呢?這看起來好像不對啊?博客怎么會發(fā)布呢?博客自己發(fā)布自己?什么鬼?不通啊!
?
確實(shí)不通,不過是你自己沒“通”;或者,一開始就錯了。
要理解這個問題,就得回到面向?qū)ο蟮摹捌瘘c(diǎn)”,明白“面向?qū)ο蟆币鉀Q的問題,不是什么“映射客觀世界”,就這個問題,也還談不上什么“繼承多態(tài)”(“封裝”勉勉強(qiáng)強(qiáng),但根還不在這里)。
讓我們再回頭復(fù)習(xí)遍:已經(jīng)有了一堆一堆的方法,再引入一個又一個的“類”,目的是什么?把方法裝進(jìn)一個又一個的類里面,分門別類,是不是為了照顧我們的“大腦”——這可憐的資源有限的人腦?電腦就沒這些麻煩,方法都不用,01010010000101001001……就OK了。所以,假設(shè)有50個類,是不是每個類里的方法數(shù)目都差不多,勻稱一些,我們的分類就更有意義一些?
假設(shè)User.Publish(Blog)的邏輯成立的話,是不是還會有User.Publish(Comment),User.Agree(Blog),User.Logon(),……,User.FlyToSky()……一個系統(tǒng),是不是幾乎所有的操作,都是User干的?這User不是要上天啊!我們“分門別類”的工作,是不是就沒有意義了?以前是記一堆函數(shù),現(xiàn)在是記User下面的一堆函數(shù),有個毛用啊!
?
但我經(jīng)常看到類似User這樣的萬能類,有輕重程度的差別,但本質(zhì)上,這種代碼,就是“披著‘面向?qū)ο蟆钠ぁ?#xff0c;干著……干著什么事呢?干著亂七八糟的事。
當(dāng)然,還有濫用繼承,層層疊疊的像個十八層寶塔一樣,又百轉(zhuǎn)千回的像個死亡迷宮一樣,你咕噥一句“整復(fù)雜了”,架構(gòu)師一臉傲嬌鼻孔朝天,“面向?qū)ο?#xff0c;高級貨!哪那么容易的……”
?
碼字才真心不容易——這博客從昨天寫到今天,差不多了。
做個總結(jié)吧:
(⊙x⊙;)
?
就醬紫,我要繼續(xù)愉快的擼代碼去了,歡迎圍觀。
轉(zhuǎn)載于:https://www.cnblogs.com/freeflying/p/7410167.html
總結(jié)
以上是生活随笔為你收集整理的十年之后再看“面向对象”的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用Python爬虫爬取炉石原画卡牌图片
- 下一篇: 使用@required注解完成依赖检查