五分鐘理解什么是面向?qū)ο?/h2>
7 評論 106749 瀏覽 267 收藏 8 分鐘

昨天講了MVC,有同學(xué)表示還想了解一些軟件開發(fā)架構(gòu)方面的姿勢。我琢磨了半天,列了不少技術(shù)名詞,本來想挑一個(gè)出來講一講,寫了一半發(fā)現(xiàn)有很多前置知識之前沒涉及,于是決定把坑填一填,先從基礎(chǔ)的「面向?qū)ο蟆怪v起。

話說起來,面向?qū)ο蟮漠a(chǎn)生還有各位產(chǎn)品經(jīng)理的功勞。為什么這樣說呢?因?yàn)橐婚_始的時(shí)候,并沒有面向?qū)ο螅挥忻嫦蜻^程的概念。面向過程很好理解,指的是程序員接到需求,會(huì)把它拆成一個(gè)一個(gè)的命令,然后串起來交給計(jì)算機(jī)去執(zhí)行。舉個(gè)例子,產(chǎn)品經(jīng)理說要把大象裝進(jìn)冰箱里。程序員列了幾個(gè)步驟:

  • 把冰箱門兒打開。
  • 把大象裝進(jìn)去。
  • 把冰箱門兒關(guān)上。

上面每一個(gè)步驟,程序員都會(huì)用一個(gè)「函數(shù)」來實(shí)現(xiàn)?!负瘮?shù)」是一些代碼的集合體,每個(gè)函數(shù)可以實(shí)現(xiàn)一個(gè)功能。比如我要定義一個(gè)打開冰箱門的函數(shù):

所有函數(shù)定義好了之后,依次調(diào)用就可以了:

  • openTheDoor();
  • pushElephant();
  • closeTheDoor();

需求完成,順利交工。但是你以為這樣就結(jié)束了?Naive。產(chǎn)品經(jīng)理說才剛剛開始呢。

  • 「我要把大象裝微波爐里」
  • 「我要把獅子也裝冰箱里」
  • 「我要把大象裝冰箱,但是門別關(guān),敞著就行」
  • 。。。

如果還是用面向過程的方法來應(yīng)付,每次需求的變更,程序員就要把整個(gè)系統(tǒng)通讀一遍,找出可用的函數(shù)(如果沒有就再定義一個(gè)),最后依次調(diào)用它們。最后系統(tǒng)越來越雜亂無章難以管理,程序員不堪重負(fù),紛紛操起刀走上了犯罪的道路。

面向?qū)ο髲牧硪粋€(gè)角度來解決這個(gè)問題。它拋棄了函數(shù),把「對象」作為程序的基本單元。那么對象到底是個(gè)什么東西呢?對象就是對事物的一種抽象描述。人們發(fā)現(xiàn),現(xiàn)實(shí)世界中的事物,都可以用「數(shù)據(jù)」和「能力」來描述。比如我要描述一個(gè)人,「數(shù)據(jù)」就是他的年齡、性別、身高體重,「能力」就是他能做什么工作,承擔(dān)什么樣的責(zé)任。描述一臺(tái)電視,「數(shù)據(jù)」就是它的屏幕尺寸、亮度,「能力」就是播放《葫蘆娃》。

面向?qū)ο蟮氖澜缋铮教幎际菍ο?。對象不光有「?shù)據(jù)」和「能力」,還可以接受命令。例如你可以讓「狗」這個(gè)對象「吃狗糧」,就可以把「吃狗糧」的命令發(fā)給「狗」讓其執(zhí)行,然后我們就實(shí)現(xiàn)了「狗吃狗糧」的需求。

現(xiàn)在對象有了,如何進(jìn)行面向?qū)ο蟮木幊棠兀亢芎唵?,依次向不同的對象發(fā)送命令就可以了?;氐缴厦娴睦樱妹嫦?qū)ο髞韺?shí)現(xiàn),我們會(huì)先定義一個(gè)「冰箱」對象,它的「數(shù)據(jù)」就是當(dāng)前的冷凍溫度,或者該冰箱已經(jīng)有了多少頭大象,「能力」就是開門、關(guān)門。還有一個(gè)「大象」對象,它的「數(shù)據(jù)」可以是大象的智商、體積,「能力」就是「自己跑到冰箱里去」。然后我們依次:

  • 向冰箱下達(dá)「開門」的命令。
  • 向大象下達(dá)「進(jìn)冰箱」的命令。
  • 向冰箱下達(dá)「關(guān)門」的命令。

面向?qū)ο笥泻芏嗵匦裕憧赡苈犝f過繼承、封裝、多態(tài)的概念,但我不準(zhǔn)備在這里講這些(可能后面的文章會(huì)介紹),我就說下我理解的面向?qū)ο?,最重要的兩個(gè)特性。

自己的事情自己做。

我們創(chuàng)建的對象,應(yīng)該是剛剛好能做完它能做的事情,不多做,不少做。多做了容易耦合,各種功能雜糅在一個(gè)對象里。比如我有一個(gè)對象叫「汽車」,可以「行駛」,可以「載人」,現(xiàn)在的需求是要實(shí)現(xiàn)「載人飛行」,就不能重用這個(gè)對象,必須新定義一個(gè)對象「飛機(jī)」來做。如果你給「汽車」插上了翅膀,賦予了它「飛行」的能力,那么新來的同學(xué)面對你的代碼就會(huì)莫名其妙,無從下手。

面向接口編程。

現(xiàn)在我們把「數(shù)據(jù)」和「行為」都封裝到了對象里,相當(dāng)于對象成了一個(gè)黑匣子,那我們怎么知道對象具有什么樣的能力呢?這個(gè)問題的關(guān)鍵就是接口。關(guān)于接口,之前的文章《5分鐘理解什么是接口》有過介紹。對象把它的能力通過接口的方式公布出來,自己則成為接口的實(shí)現(xiàn)者。這樣調(diào)用者就不用關(guān)心接口背后的對象是什么東西,如何實(shí)現(xiàn)的了。還是上面的例子,產(chǎn)品經(jīng)理現(xiàn)在說要把大象放洗衣機(jī)里,通過我們的分析,洗衣機(jī)也需要有「開門」、「關(guān)門」的能力。那么我們就可以抽象出一個(gè)接口來,它就是「開門」和「關(guān)門」的能力集合,假設(shè)我們稱之為「大象之家」接口。我們的對象冰箱、微波爐、洗衣機(jī)都實(shí)現(xiàn)「大象之家」的接口,盡管實(shí)現(xiàn)方式不一樣,但是在外界看來,它們都是一樣的,都是可以盛放大象的容器。這樣我們編程的時(shí)候就可以這樣寫:

  • 向大象之家下達(dá)「開門」的命令。
  • 向大象下達(dá)「進(jìn)冰箱」的命令。
  • 向大象之家下達(dá)「關(guān)門」的命令。

至于大象之家到底是個(gè)什么東西,我們不care。即使哪天變成了馬桶,「開門」和「關(guān)門」的具體實(shí)現(xiàn)交給負(fù)責(zé)馬桶對象的同事,我們只管調(diào)用就可以了。

面向?qū)ο缶拖戎v這些吧,封裝、繼承和多態(tài)暫且當(dāng)做一個(gè)坑,以后來填。年紀(jì)大了好忘事兒,你們?nèi)绻肓私獾脑?,記得提醒我哈?/p>

#專欄作家#

給產(chǎn)品經(jīng)理講技術(shù),微信公眾號(pm_teacher),人人都是產(chǎn)品經(jīng)理專欄作家。資深程序猿,專注客戶端開發(fā)若干年,對前端、后臺(tái)技術(shù)略懂,熱衷于對新的科技領(lǐng)域的探索。

本文原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理,未經(jīng)許可,不得轉(zhuǎn)載。

更多精彩內(nèi)容,請關(guān)注人人都是產(chǎn)品經(jīng)理微信公眾號或下載App

評論
評論請登錄
  1. 是否程序的世界里,所有的方案都要基于面向?qū)ο髞碜??面向過程就徹底被廢棄了嗎,是否在某些場景下還是有用武之地。

    回復(fù)
  2. 世間萬物皆為對象;然而你如何去解釋一個(gè)對象到底是啥…

    來自湖南 回復(fù)
  3. 不錯(cuò),通俗易懂。希望接著講對象的特性

    回復(fù)
  4. 不錯(cuò),通俗易懂。希望接著講對象的特性

    回復(fù)
  5. 通俗的講法很好,但是我覺得您得繞回來,實(shí)戰(zhàn)過程中,誰是大象,誰是門,門哪來,用一個(gè)最常見的例子說明可以嗎?比如作為程序員,面向?qū)ο蟮拈_發(fā),第一步是xxx,相當(dāng)于“找大象”,第二步,從哪調(diào)接口xxxxx,相當(dāng)于“找門”。對應(yīng)的講我覺得比較好,感謝!

    來自北京 回復(fù)
  6. 越解釋越亂……

    來自廣東 回復(fù)