在7月6日我們迎來了第一期微課堂分享,,是由陳勇老師帶來的程序員的四重境界,,可能有的朋友當(dāng)時沒有參與進(jìn)來,。下面是根據(jù)老師的口述,,整理的一篇文稿。 程序員的四重境界 先說一說程序員的四重境界是哪里來的,?大約在2001年的時候,,我參加了一個非常好的團(tuán)隊(duì),在這里遇到了我的師傅,。在遇到我的師傅之前我已經(jīng)工作了6年了,,但是我的編程水平怎么樣呢?我當(dāng)年做的是C++,,我不會寫泛型,,不會用虛函數(shù),還不會刪內(nèi)存,。然后我的師傅用了兩個星期就教會了我所有這些東西,,也正是在這個團(tuán)隊(duì)里,我們偶然地看到了一篇當(dāng)時csdn上面的帖子,,帖子的名字就是程序員的四重境界,,很可惜印象中他并沒有解釋是從境界的含義,但是寫了這4個名字,。 第一重,,編寫可用代碼,第二重,編寫高質(zhì)量代碼 好了說完這兩個級別我就先一個級別一個級別解釋,,待會兒咱們再看剩下的兩個級別,。 第一個是可用代碼,這是個什么狀態(tài)呢,?就是大家想一想,,本科程序員畢業(yè)之后基本上就在干這件事情。因?yàn)樵谖覀冋降拇髮W(xué)教育里面,,我們只需要學(xué)會語法就可以,,并沒有要求我們?nèi)ゾ帉懗龆嗝锤哔|(zhì)量的產(chǎn)品了。確切的說,,我們大學(xué)里邊寫的所有程序,,沒有一個經(jīng)過測試的。所有的考試都是你能編出什么東西來就可以了,,這里面是不是要做異常處理,,誰去管呢。 下一個問題是我們?nèi)粘9ぷ髦袑?shí)際上無時無刻都會面臨這樣的程序員,,他們剛剛加入了我們的團(tuán)隊(duì),,那么這個時候,關(guān)鍵的一個問題是讓他們的編碼水平和它們的代碼分離,。借用諾頓所說過的一句話,,就是用不可靠的程序員編寫可靠的代碼,所以有的時候我們也經(jīng)常聽說,,讓某某某來負(fù)責(zé)一個小模塊,,獨(dú)立完成工作鍛煉一下。但這種做法其實(shí)是錯誤的,,設(shè)想一下我們編寫的,,是航天飛機(jī)里面的軟件,有人想讓他去鍛煉一下嗎,?雖然多數(shù)時候我們編寫的軟件還不至于這么嚇人,,但是我也很難在我一生之中做的所有軟件里挑出一個來,是可以允許用來把鍛煉人當(dāng)作其中一個目的的,。所以,,對于編寫可用代碼級的人,很重要的一點(diǎn)就是要有人去知道,、有人去把關(guān),,看到他編寫的每一行代碼,并且確保每一行代碼都是可以放到正式產(chǎn)品中的,。 那這個呢,,我們常用的一種方法就是139團(tuán)隊(duì),。139團(tuán)隊(duì)指的就是1個大的領(lǐng)導(dǎo)、3個師傅,、9個新手徒弟,。這樣的話,新手就可以在可用代碼級別上,,但是他們所編寫的所有代碼,,都必須經(jīng)過自己相應(yīng)的師傅,審查之后才可以進(jìn)入產(chǎn)品,,同時這個審查過程也是一個知識傳遞的過程,,也就是說我們改進(jìn)的并不完全是代碼,還包括徒弟的編程水平,。我當(dāng)年的師傅,,手底下只有我們3個徒弟,他每天都會看我們編寫的代碼,,并且當(dāng)場指出我們存在的問題,,除了改好代碼之外,他還會告訴我們?nèi)绾斡谰玫乇苊膺@個問題,,這些避免問題的方法本身就是我們要學(xué)習(xí)的內(nèi)容,。如果徒弟的代碼經(jīng)過了審查才進(jìn)入代碼庫,那么就相當(dāng)于徒弟的水平和他編寫的代碼已經(jīng)分離了,。換言之,,他正在以師傅的水平編寫代碼。 第二個級別我們再說一說高質(zhì)量的代碼確切的說有些人可能會非常驚訝,,因?yàn)槲覀円还舱f了四個層級,,居然高質(zhì)量只能排在第二,。那么什么樣的代碼,?可以被稱之為高質(zhì)量的,整體上包含兩個層面的東西,。 第一個層面,,是現(xiàn)在的代碼編出來就是高質(zhì)量的,因此,,在現(xiàn)在的測試環(huán)節(jié)以及和別人,、多聯(lián)機(jī)調(diào)試的時候不會出現(xiàn)太多缺陷。所以這一點(diǎn)上我們有的時候會看到有些程序員說什么呢,?他們說你們盡管測吧測出來缺陷我改,,這種程序員,第二級都達(dá)不到,,確切的說是連2.1級都達(dá)不到,,那么要達(dá)到2.2級,還需要保證我們的軟件在未來沒有缺陷。有很多代碼剛剛編出來的時候還是可以的,,但后來,,自己改來改去或者別人改來改去,就開始出現(xiàn)問題,。原因主要是,,代碼可能在一致性、可維護(hù)性上,,存在問題,。 比如我問大家一下,有一個類,,有5個成員變量,,每次聲明這個類之后,5個成員變量都要被初始化一下,。但是后來,,出現(xiàn)了第6個成員變量,因此有的地方忘記了修改,,沒有進(jìn)行初始化,,請問大家應(yīng)該怎么辦? 如果我們構(gòu)造的完成一次整體初始化,,問題就解決了,。當(dāng)然這是一種比較簡單的情況,類似的情況還會發(fā)生很多,。比如最常見的switch-case,。我們可能在好多地方都要進(jìn)行分支,假設(shè)有10種不同的類型,,在這個地方要使用上面提到的switchcase語法進(jìn)行一次分支,,在遙遠(yuǎn)的地方還要進(jìn)行一次分支,在更遠(yuǎn)的遙遠(yuǎn)的地方還有好幾次,,那么類似這樣的代碼日后遲早會出錯,,因?yàn)槿藗兏膩砀娜ゾ腿菀淄浧渲幸粋€地方。而且每次改變的什么東西都需要滿街找相關(guān)的地方,。這個大家覺得應(yīng)該怎么辦,? 具體是哪個模式呢?最好能直接說出那種語法來,,因?yàn)槲移鋵?shí)不記得太多模式,。不同的語言可能有不同的語法來處理,最簡單的東西其實(shí)就是虛函數(shù),。虛函數(shù)就是多態(tài),,簡單的說就是不同的類型處理這種方法,,走到這一步的時候運(yùn)行的東西不一樣,那么我們可以把這件事本身起一個函數(shù)名,,但是每個類型都重新寫這個函數(shù),,因此運(yùn)行的內(nèi)容就不一樣。是的繼承,,然后再寫程序函數(shù),。面向接口也一樣的,我們可以認(rèn)為接口是一個虛函數(shù),。 C++和C#,,要專門指出,哪些函數(shù)是虛的可以被重載的,,Java似乎不需要,。接口就是多態(tài)的實(shí)現(xiàn)方式之一,確切的說我發(fā)現(xiàn),,如果你想做多重繼承但是這種語言又不支持,,那么接口就是一個很漂亮的實(shí)現(xiàn)。我的代碼里一個這個東西都沒有,,除了微軟自動生成的3個,,只有在一種特殊的環(huán)境里才需要他。所以剛才我們提到的這些語法他們之所以產(chǎn)生就是為了解決未來的質(zhì)量問題,,因?yàn)橛行〇|西現(xiàn)在卸下來沒關(guān)系,,但如果他很難讀很難維護(hù),遲早會造成長期以后出現(xiàn)問題,。有一種語法,,和他是一樣的,那就是if else if else,。這個東西也一定要消滅干凈,。好了說完了高質(zhì)量代碼的兩個子層次,我們再看看第三大層,。 程序員的第三層境界叫做編寫精美的代碼 什么是精美的代碼呢,?簡單的說就是兩個字,,第一個叫精,,第二個叫美。盡量不要用或者說傾訴一下,,仔仔細(xì)細(xì)看一下,,可以用虛函數(shù)給它干掉。 什么是精呢,?就是代碼越少越好,。不過這里說的少,,不是說把那些非常多的代碼給強(qiáng)行弄到一行代碼里去。而是說在設(shè)計(jì)整個軟件的時候,,要想清楚如何通過分層,、復(fù)用來使得多數(shù)代碼被調(diào)用多次以上。分層的基本原則就是VCMD V就是界面層,,也就是說有些功能是在界面上的,,但是和界面無關(guān)的東西,一定要分層到別處去,。比如控件,,比如業(yè)務(wù)邏輯。 C就是controller,。這一層可能是最難理解的,,如果大家看過微軟的asp.net mvc官方代碼,就會發(fā)他的每一個action方法里面,,代碼行數(shù)不會超過5行,。因?yàn)檫@些代碼只負(fù)責(zé)用來解決權(quán)限管理,正確的訪問之后去哪里,?錯誤之后去哪里,?至于具體的業(yè)務(wù),都在下一層里面,,因此才給它起名字叫做controller,。所以千萬不要在里面跑業(yè)務(wù)單或者任何和數(shù)據(jù)庫訪問相關(guān)的東西。業(yè)務(wù)代碼,,只要碰到業(yè)務(wù)都寫到model,,但是做這一層,也要再分不同的層次,。比如上層的業(yè)務(wù),,抽象之后類的業(yè)務(wù)等等。這些就是了,,代碼的層級變得很干凈,,即使代碼的整體行數(shù)并沒有因?yàn)榉謱佣鴾p少,但是我們會發(fā)現(xiàn)另外幾個現(xiàn)象,。 第一,,我們可以選擇性的閱讀了,也就是說,,如果我覺得業(yè)務(wù)有問題,,那么我就選擇業(yè)務(wù)代碼,如果我覺得技術(shù)有問題,,我就去讀技術(shù)的嘛,,如果我覺得控制流程有問題,,我會再看上層的代碼。第二,,現(xiàn)在可以復(fù)用了,,換言之本地代碼并沒有變少,但是別處省了很多代碼,。第三,,維護(hù)起來簡單多了,因?yàn)橐郧暗臅r候很多地方都有散裝的代碼,,但是現(xiàn)在他們都有統(tǒng)一的地方,,在相應(yīng)的層次上進(jìn)行了封裝,只要改這一個地方就可以了,。合法性檢查經(jīng)過了若干代的變遷,。 比如在現(xiàn)在的微軟的m vc框架里面,他的聲明是在model里面進(jìn)行的,,但是微軟在形成前端代碼的時候,,會把聲明放在前端進(jìn)行檢查。他認(rèn)為只有編寫模型的人才能真正理解,,到底應(yīng)該做哪些數(shù)據(jù)檢查,?而這些數(shù)據(jù)檢查的時機(jī),又應(yīng)該是在前端提交表單之前,,因此他才設(shè)計(jì)了這種機(jī)制,。關(guān)于查詢條件的組合,因?yàn)槲覀儸F(xiàn)在使用的是entity framework,,所以我們把語法寫在業(yè)務(wù)模型中,,而最終執(zhí)行卻是微軟自己控制的,我也不知道他在哪一層執(zhí)行了,。這是微軟首推的方法所以我們也就采納了,,防住攻擊也在ef中完成了。注入攻擊,,好了具體的技術(shù)可能每種語言發(fā)展的階段不同,、官方的策略不同都會有區(qū)別。但是關(guān)鍵的一點(diǎn)就是一定要利用分層把代碼變的精致,。 第二個特點(diǎn)就是美,。美,也是用分層來實(shí)現(xiàn)的,。什么樣的代碼更美的呢,?我覺得這個時候要看讀代碼的人的心情。他想讀什么就讀到了什么,,這個時候在他眼中代碼是美麗的,。比如,我們當(dāng)年曾經(jīng)有一段代碼描述的是數(shù)字電視中的碼流,,這些碼流有一些奇特的特性,,比如,布爾值必須使用1位,,而數(shù)值不超過256的整數(shù)也只給你8位,。總之最后導(dǎo)致我們的傳進(jìn)去的數(shù)據(jù)要精確的定位到位,。而有一位程序員就手工計(jì)算了每一個位置,,然后在代碼中寫了無數(shù)個常數(shù),每當(dāng)這些位置發(fā)生變化都是一場災(zāi)難直到后來出現(xiàn)了問題,。為什么說這個代碼是不美的呢,?因?yàn)楫?dāng)他想看某一個代碼,中間要插入一個新的數(shù)字的時候,,他不只是要看那個數(shù)字,,還要看后面被他影響到的所有的數(shù)字,影響到了人的心情,。同樣的,,我們的業(yè)務(wù)發(fā)生變化我們就看業(yè)務(wù)代碼,技術(shù)發(fā)生變化就看技術(shù)代碼,,加密算法升級了就改一個加密的算法,,剩下的東西我們都不應(yīng)該去看去找,這樣的代碼就是美的,。最后怎么做的呢,?最后我們做了一個自動打包器,你只要告訴他說,,放進(jìn)一個什么數(shù)字占多少位,,它會自動計(jì)算當(dāng)前的位置。以后要拿出來的時候,,只要說請把它拿出來,,它也會自動計(jì)算一下該到哪里去拿,所以我們有110行的打包器的代碼,,放在底層從來沒有人動它,,還有一些對打包器的調(diào)用放在上層,但是調(diào)用干干凈凈,。代碼里面我們重載了操作符進(jìn)行了連寫,,因此你看見的東西很像一篇文檔而不像一些代碼。這使得原來的4000行代碼只用了700行就實(shí)現(xiàn)了,,4000多個常數(shù)被76個常數(shù)代替,。這76個常數(shù)來自于數(shù)字廣播標(biāo)準(zhǔn),,每一個都是不可或缺的,所以才需要被保留,。有了這段代碼以后每增減一個數(shù)字只需要一分鐘左右,,拷貝粘貼修改其中一行或者刪掉它。代碼不但變得少了而且更容易讀了,,因此我們說精和美,,并不是兩者只能選擇其一。往往是兩者相輔相成,。因?yàn)槲医?jīng)常聽到有些新手說,,如果我們現(xiàn)在把代碼縮小到更短可能就不好讀了,其實(shí)是一種錯誤理解,,真正的高手不會這樣,。 好了下面說一說第四層,叫做,,編寫思想深邃的代碼,。 什么叫做思想深邃的代碼呢?在2001年我們看到還有這樣一層的時候都笑了,,因?yàn)閷λ簧趵斫?。后來我們逐漸意識到世界上的語言千變?nèi)f化不斷推陳出新,同一種語言也在不斷的改進(jìn),,每一次改進(jìn)都是深邃的思想的結(jié)果,。當(dāng)然對我們普通的程序員而言,我們并不去設(shè)計(jì)這些語言我們只是利用他,,那么我們?nèi)绾伪憩F(xiàn)出思想深邃的一面呢,! 下面就看一看,我們普通程序員的,,三小層思想境界,。也就是說,第四層又分為三小層,。 第一小層是與大師共振,。所謂共振,就是當(dāng)我們看到一個新的語法新的功能的時候,,應(yīng)該一見如故,,因?yàn)槲覀円蚕M财诖霈F(xiàn)這個功能。很多時候我們會發(fā)現(xiàn),,一些新手對于一些語法很長時間都學(xué)不會,,就像我之前說的自己不會泛型、不會虛函數(shù)。而每一種新的語法,,都是為了解決一些可怕的問題才被設(shè)計(jì)出來的,。但如果我們不把這些問題當(dāng)問題,那么就永遠(yuǎn)學(xué)不會那種語法,。比如,,我在使用泛型和虛函數(shù)之前,,代碼中有很多重復(fù)的代碼,,很多已維護(hù)的else if, switch case。但是因?yàn)槟莻€時候我的水平只有高質(zhì)量的第一層,,所,,也不覺得未來維護(hù)他是一個重要而且痛苦的事情。如果思想中有這個想法,,那么就很難理解泛型和虛函數(shù)到底要做什么,,反而覺得他們很累贅。所以未來大家對自己編碼中,,讓自己感覺很不舒服的地方一定要深惡痛絕,,進(jìn)而做到趕盡殺絕。這一點(diǎn)剛開始很難,,但是逐漸的我們會突然發(fā)現(xiàn),,原來大師們設(shè)計(jì)的一些新語法,就是來幫助我們完成這個任務(wù)的,。而當(dāng)我們學(xué)會了這些新語法,,這些讓我們深惡痛絕的地方甚至連出現(xiàn)都不會出現(xiàn)了。比如我們現(xiàn)在的代碼一共有2500行,,里面沒有任何一個switch case,,沒有else if,連else都只有兩個,。原因就是在趕盡殺絕他們的時候,,我們突然領(lǐng)悟到了一些語法的真實(shí)含義,而熟練掌握這些語法之后這些東西根本就不出現(xiàn),,也不用費(fèi)力去趕盡殺絕了,。所以后來我沒有猜測,某些讓人不舒服的東西是有辦法解決的,,果然,,有些新出現(xiàn)的語法或框架就解決了它。所以我們未來要牢記住一點(diǎn),,一定要把糟糕的東西當(dāng)作糟糕的東西而不要姑息他們,,這個時候我們就很容易學(xué)會那些,大師設(shè)計(jì)的用來解決這些糟糕的東西的方法。 第二小層叫做手中無刀,。這是一個很奇特的概念,,大致的說法就是我們已經(jīng)忘記了具體的招式,但是我們做出來的東西仍然不差,。有的時候大家會隨手用一個泛性,,隨手用一個虛函數(shù),隨手寫下了什么東西,。然后再放眼望去,,代碼中沒有任何重復(fù)的難以維護(hù)的東西,至于我們到底用了什么模式,?自己也說不清楚就進(jìn)入了這個狀態(tài),。這個時候,確切的說我們相當(dāng)于大師們在創(chuàng)造設(shè)計(jì)模式的初期的收益水平,。那個時代天底下還沒有給設(shè)計(jì)模式起名字,,但是設(shè)計(jì)模式卻已經(jīng)在那里了。所以未來我們真正學(xué)會一個設(shè)計(jì)模式,,不是能記住他的名字,、記住它的用法、記住它的使用場景,,而是當(dāng)那個場景出現(xiàn)的時候,,我們會隨手寫出來。這就要求我們在骨子里,,對于我們的產(chǎn)品的代碼有著很高的要求,。在精美之上仍然有更精美,時間長了設(shè)計(jì)模式自己會送上門來,。當(dāng)然不完全是設(shè)計(jì)模式,。 第三小層是可以自主創(chuàng)新。很重要的一點(diǎn),,現(xiàn)在的所有語言,、框架、工具,、設(shè)計(jì)模式都是人類創(chuàng)造的,。因此我們除了能夠?qū)W習(xí)和掌握他們之外,我們也能創(chuàng)造它們,。這一點(diǎn)國內(nèi)的創(chuàng)新可能很少,,因?yàn)槲覀兊闹饕ぷ魇鞘褂眠@些東西,很少有人去真正研究他們,。但在國外我們可以看到,,很多普通的人他們設(shè)計(jì)了完全全新的框架,,自動化測試的各種框架,m vv m等等,。其實(shí)這些人也是凡人,,只不過是他們總是在思考,并且在沒有一個東西的時候,,不是在等待而是自己親自動手,。所以未來我們也要把握住這一點(diǎn),如果我們?nèi)匀桓杏X代碼有點(diǎn)讓我們不舒服,,而世界上別人又解決不了,,那么我們就親自動手解決。確切說我們自己曾經(jīng)做過一些改進(jìn),,比如說在早期的asp.net mvc中,,每一個action里面都有一個非常難看的try catch,。我們覺得他很不舒服就想辦法在全局去抓這個異常,,從而使得代碼變得更干凈,到了第五代官方已經(jīng)自己做了這些事情,。在往上可能還會有更高的層次,,但是我發(fā)現(xiàn)除非我們能達(dá)到那里,否則無法精確地描述他們,。未來可能會有高人再畫出更高的層次,。 下面我再補(bǔ)充一點(diǎn)點(diǎn)內(nèi)容吧,就是關(guān)于這4個層次到底給我們帶來了什么樣的啟示,? 我初三的時候很喜歡打乒乓球一直打到大學(xué),,到了大學(xué)里我們還專門報(bào)了乒乓球班,所以水平也不差,。然而有一天學(xué)校里來了一個大人帶著一個8歲的小孩,,這個小孩可以輕松秒殺掉我們那一隊(duì)乒乓球班的人,而那個大人也是他的父親能夠干掉我們校隊(duì)的教練,。到底發(fā)生了什么能夠讓8歲小孩戰(zhàn)勝我們呢,?我認(rèn)為是一種職業(yè)訓(xùn)練,他在剛剛出道的時候,,就被按照第四層的標(biāo)準(zhǔn)進(jìn)行訓(xùn)練,。而我們因?yàn)樽约簞倓倢W(xué),所以給自己定了非常低的目標(biāo)瞎打瞎鬧,。所以盡管我們打乒乓球的時間比他長的多,,但是水平卻差得多。所以我認(rèn)對于普通的程序員,,如果他們能夠在初學(xué)軟件的時候就像思想深邃看齊,,那么他們可以少走很多彎路,。 那么如何找到思想深邃的人呢?我覺得遠(yuǎn)在天邊近在眼前遠(yuǎn)在天邊的人,,是那些官方代碼,。有很多人學(xué)習(xí)編碼是隨便找一本書就看的,我覺得還是應(yīng)該到官方里面去找真正的高手寫的書,。除了這些圣賢之書之外剩下的盡量少看,,這樣我們直接就可以學(xué)到編碼的精髓。其次,,身邊一定會有各路高手,,對于這路這些高手而言,他們可能未必能達(dá)到第四層,,但是也一定有可借鑒之處,。可以作為一個方向,,對我們某些不能理解的東西答疑解惑,。 問答: 問:那么if else如果大于3層,該怎么辦,?經(jīng)常會用到知道很煩,,但是不知道怎么去掉。 答:反正我們的產(chǎn)品里沒有,?;蛘哒f即使刪掉這個語法,一樣可以干活,。和switch case是同一個東西啊,,用相同的方法可以干掉。我們在1萬行代碼的產(chǎn)品里都沒有的?,F(xiàn)在的產(chǎn)品只有2500多行,,也一個都沒有。 問:如何判斷是否變量是否為空,? 答:這種情況盡量使用一種結(jié)構(gòu)叫做false false true,。就是先處理異常情況,盡早返回錯誤,,然后這樣就是if,,if,最后連else我用不上了。有沒有縮進(jìn),。這個和剛才說的情況不一樣,,它不是一種分支結(jié)構(gòu),是流程扭轉(zhuǎn),。也就是說,,盡量不要產(chǎn)生縮進(jìn),。這會使得語句變長難以理解。扭轉(zhuǎn)一下流程就好了,。 問:如果業(yè)務(wù)邏輯大的話要分很多函數(shù),,這樣讀起來產(chǎn)生思維跳躍,不停找到定義它的函數(shù)來實(shí)現(xiàn),。 答:業(yè)務(wù)邏輯可以把上層業(yè)務(wù)和下層業(yè)務(wù)做一些分成,。比如我們當(dāng)年曾經(jīng)有一個東西是做權(quán)限控制的,總公司的人可以看見分公司的,、分公司的負(fù)責(zé)人可以看見部門的,、部門的負(fù)責(zé)人可以看見團(tuán)隊(duì)的、團(tuán)隊(duì)的負(fù)責(zé)人可以看見小組的,、小組的負(fù)責(zé)人可以看見自己寫的模塊,、自己的模塊的負(fù)責(zé)人可以看見模塊下屬的史詩故事、史詩故事的負(fù)責(zé)人可以看見用戶故事,、用戶故事的負(fù)責(zé)人可以看見用戶故事的測試用例,、用戶故事測試用例的負(fù)責(zé)人可以看見因?yàn)檫@個測試用例而產(chǎn)生的缺陷。這個東西如果用簡單的寫法一定會臭長無比,,我們就做了一個底層類把剛才所有東西都設(shè)計(jì)了一個基類,,所有類型都有一個父親,父親的負(fù)責(zé)人可以向下面所有的東西自動繼承權(quán)限這樣上面寫應(yīng)用的人就不用再管權(quán)限問題了,。 如果擔(dān)心思維跳躍,很重要的一點(diǎn)就是一定要跳過去那些我們不該讀的東西,。比如我要讀的是上層業(yè)務(wù),,我就不看下場是怎樣實(shí)現(xiàn)的,這樣就不跳躍了,。否則無論分層或者放在一起思維都難免跳躍,,可能有的時候老想看看這個東西是怎么實(shí)現(xiàn)的,不過我現(xiàn)在對自己的代碼經(jīng)常都不記得,,因?yàn)槲覀冊?萬多行的代碼里大約有2000個函數(shù),,或者說每個函數(shù)只有5行。我是說有的時候我們程序員特別想看看代碼內(nèi)部是怎樣實(shí)現(xiàn)的,?但其實(shí)以后要放棄這個習(xí)慣,,因?yàn)槲覀儜?yīng)該逐漸忘掉某些事情是怎樣實(shí)現(xiàn)的,這樣才能把精力集中在當(dāng)前要實(shí)現(xiàn)的業(yè)務(wù)上,。 問:剛才說的權(quán)限問題,,有個問題是經(jīng)過管理員授權(quán)你也可以看到任何層級的權(quán)限,這樣的話有沒有更好地方法,。 答:那就在基類里面寫上一個(或多個)被授權(quán)的用戶,。任何一個人都會問當(dāng)前用戶,,是我的負(fù)責(zé)人嗎、是我的父親的負(fù)責(zé)人嗎,、是我的祖父的負(fù)責(zé)人嗎等等等等,,再問是一個被特殊授權(quán)的負(fù)責(zé)人嗎?因此授權(quán)問題我們就永遠(yuǎn)忘記他,,因?yàn)槲覀兊幕惪梢越鉀Q它,。剩下的就是我們做了授權(quán)到底要做什么呢?這才是我們真正要干的事情,。這樣做還有一個好處,,就是任何一層都不可能出錯,因?yàn)槭撬麄兪怯泄餐囊粋€機(jī)制完成的,,不會因?yàn)槲覀兎止f(xié)作有些新手就把事情搞大了,。 問:如果身邊真的沒有像樣的高手指導(dǎo)呢? 答:嗯,,那就多看書吧,,一定要多學(xué)習(xí)官方編碼,并且在自己的代碼任何時候?qū)懙牟幌窆俜綐?biāo)準(zhǔn)的時候都要更正,,千萬不要積少成多,。我當(dāng)年看了微軟的副總裁寫的m v c的代碼,跟他學(xué)習(xí)了所有的編碼規(guī)范,,力求所寫代碼沒有一個地方能讓他認(rèn)出來有問題,。 問:你們項(xiàng)目對于一般接口的一系列的驗(yàn)證怎么做,難道是一堆if else嗎,? 答:是指檢查接口送進(jìn)來的東西是否符合要求嗎,?在微軟的mc框架里面,他會嘗試把送進(jìn)來的數(shù)據(jù)封裝到一個類里面,。這個類每一個成員變量都有一個attribute對他進(jìn)行檢查,,所以只要這個東西寫好了,它就會自動對他進(jìn)行全面檢查,。這樣就避免了對于大堆散裝數(shù)據(jù)的挨個檢查,。 問:Java應(yīng)該也可以這樣做吧? 答:我覺得應(yīng)該有吧,,雖然我沒用過,。因?yàn)檫B我都能想到的東西大師們不應(yīng)該放在那里不做。是的這兩種語言競爭很久了,,應(yīng)該在相同的水平上,。有一段時間我去摸索移動端代碼編程,我發(fā)現(xiàn)所有檢查都還沒有封裝起來,。甚至還有很多類似getViewByid,。因?yàn)槲矣玫囊苿佣碎_發(fā)使用C#編寫的,,所以我就用反射做了一個自動映射,差不多70%的代碼都可以省掉了,,那個還是他們推薦的官方代碼,。如果官方能夠派幾個人多研究一下其他平臺的編程技術(shù)的最新進(jìn)展,他們早該自己完成這個工作,,用的也是attribute,。 此文章未經(jīng)作者審閱! 想要收聽更多的干貨分享嗎,?那就加群吧,! 加群方法 掃描下面的二維碼加好友,接頭暗號「我要進(jìn)群」,。瞬間就穿越到群里,。 -- msup 研究院團(tuán)隊(duì) |
|