冒號和他的學生們
程序員提高班紀事
摘要:
軟件接口服務的主客雙方應遵循的準則
嘆號幡然反省:“以前我們做OOP編程時,總是專注于如何利用其他類來解決問題,而較少考慮自己設計的類對其他類的影響。”。。。
作為服務的提供者,最重要的是講誠信。首先,服務要有可靠性,不能陽奉陰違——即接口必須履行它的承諾;其次,服務要有穩定性,不能朝令夕改——即接口一經公開,不得隨意變更。。。
此外,高質量的服務還要有純粹性和完備性。Unix有一個哲學:‘一個程序只做一件事,但要做好’。用在OOP上,則是:‘一個類只提供一套服務,但要完善’。。。
關鍵不在于服務數量的多寡,而在于服務的一致性和關聯性。。。
作為服務的享受者,最重要的是講規矩。。。
以違背服務初衷的方式享受的服務,如同盛夏的豆腐——即使沒有變質,也是不能持久的。。。
閱讀全文
摘要:
OOP中的訪問控制
問號提問:“信息隱藏是否專指用private來控制訪問?”。。。
初級程序員的理想是為所欲為——能用編程解決一切問題;中級程序員的理想是盡善而為——追求最佳解決方案;高級程序員的理想是有所為有所不為——重在整體設計的選擇,能抵制局部技巧的誘惑;最高理想是無為而無不為——無論宏觀設計還是微觀實現,均非刻意選擇,卻自然合度。。。
從軟件應變的角度來看,訪問控制是對修改所帶來的副作用的控制。。。
客戶意識對一個程序員的重要性,絲毫不亞于對一個企業的重要性。。。
千萬不要為追求廉價的重用而輕易擴大接口范圍,莫以自身之便而致客戶之不便,莫以一時之便而致長期之不便。。。
閱讀全文
摘要:
適應變化的能力是衡量軟件質量的重要標準
第七課剛一開堂,冒號就提了一個問題:“如果把一個Java程序中所有的private關鍵字換成public,請問該程序還能工作嗎?”。。。
軟件的難點有二:其一是邏輯的復雜,其二是需求的變化。許多程序員看重前者而看輕后者,大部分時間花在尋求解決方案上,而不是在選擇解決方案上。。。
軟件之軟,體現在適應變化的能力。。。
軟件的變化大致分兩種:一種是出于內在需求而作的結構性變化,通常以改善軟件質量為目的,即所謂的重構(refactoring);一種是出于外在需求而作的功能性變化,通常以滿足客戶需要為目的。。。
信息隱藏雖能將抽象接口與具體實現分離,但仍然封裝在同一類中。橋梁模式則讓二者徹底解耦(decouple),增強了對變化的適應力,具有更大的靈活性和可擴展性。。。
閱讀全文
摘要:
OOP中的封裝與信息隱藏
“用廣東話說,真是有型有料又有性格啊!”嘆號嘖嘖連聲,“這哪里是在設計軟件,分明是在設計心儀的對象嘛。”。。。
廣義的封裝僅僅只是一種打包,即package或bundle,是密封的但可以是透明的。。。
狹義的封裝是在打包的基礎上加上訪問控制(access control),以實現信息隱藏。。。
抽象意味著用戶可以從高層的接口來看待或使用一類對象,而不用關心它底層的實現,而黑盒封裝意味著用戶無權訪問底層的實現。。。
訪問控制不僅是一種語法限制,也是一種語義規范。。。
“通,則大處圓融合一而小處各具其妙;不通,則大處千變萬化而小處無所分別。”冒號又打起了禪語 ,“領會OOP的精髓絕非一年半載之功,但若以抽象與封裝為鑰,必可早日開啟通達之門。。。”
閱讀全文
摘要:
介紹抽象數據類型
問號搶著說:“我知道了:過程抽象的結果是函數,數據抽象的結果應該是數據類型。”。。。
數據結構強調具體實現,側重應用;抽象數據類型強調抽象接口,側重設計。。。
接口是綱,實現是目。綱若不舉,目無以張。。。
人們多采取‘整體設計以數據為中心,局部實現以算法為中心’的方針,以增強系統的可維護性。。。
數據類型的接口與實現的分離,有利于開發時間的分離以及開發人員的分離。。。
抽象——接口與實現相分離;數據——以數據為中心組織邏輯;類型——單純而定義良好的概念。。。
抽象——尤其是數據抽象——才是OOP的核心和起源,盡管它們并非OOP的專利。。。
只有貫徹ADT思想,設計出來的類才會是‘萬人迷’:有優雅的外形——抽象,有豐富的內涵——數據,有鮮明的個性——類型。。。
閱讀全文
摘要:
軟件設計中的抽象思維
冒號健步走進教室,學員們立刻正襟危坐,進入戰備狀態。。。
語言是形,范式是神,這次我們將二者融合,爭取做到形神兼備。。。
我們的重心不在知識的枝節,而在知識的本源。因此無論討論Java還是OOP,我們不追求系統和全面,但力求從不同的選點、角度和深度來展示知識的活性。。。
那么什么是抽象呢?不妨概括為:去粗取精以化繁為簡;由表及里以異中求同。再精煉些,抽象就是作減法和除法。。。
軟件設計者的任務是將復雜混沌的現實世界映射到精確嚴格的虛擬世界,要完成這種多對一的映射,抽象無疑是必由之路。。。
這種通過規范使代碼的功能與實現相分離的方法稱為規范抽象。。。
閱讀全文
摘要:
討論Perl、PHP、Python和Ruby 語言
“剩下四種動態語言,我們將之歸為后臺腳本語言。”冒號說著畫了張圖表。。。
Perl凝練晦澀,Python優雅明晰,Ruby精巧靈動,PHP簡明單純。。。
嘆號——沒有最好的語言,只有最合適的語言。
逗號——沒有糟糕的語言,只有糟糕的程序員。
問號——沒有一種語言是萬能的,只會一種語言是萬萬不能的。
引號——廢除對語言的宗教信仰,建立對語言的哲學思維。
句號——編程就是在人腦和電腦之間尋找最佳平衡點的過程。。。
閱讀全文
摘要:
討論VB、Delphi和JavaScript
稍事休息后,冒號切換了話題:“接下來簡單聊聊Visual Basic和Delphi。”。。。
在以網絡為中心的企業解決方案中,作為平臺語言的Java和C#是兩棵比肩而立的大樹,在它們周圍生長著郁郁蔥蔥的動態語言的小草。。。
待友之道,貴在放大其優點而縮小其缺點,對待語言亦當如此。其實JavaScript的強大和優雅是超乎想象的,它如一只神奇的魔袋,乍看平淡無奇,卻總能變出意想不到的寶貝。。。
前臺編程涉及面專,絢麗花哨的界面更容易讓初涉編程者產生成就感;后臺編程涉及面廣,需要深厚的技術積累和縝密的設計思維;底層編程涉及面深,給人神秘莫測之感。然大道相通,難者亦易,易者亦難。。。
閱讀全文
摘要:
討論Java和C#
逗號提出:“現在應該到了Java時間吧。”
冒號順水推舟:“下面談論的重心從剛才的系統語言轉到平臺語言——Java和C#。”。。。
這既是程序員之幸——語言之間可以互相取長補短,共同進步;也是程序員之不幸——往往不得不在眾多語言中作艱難選擇,或者多花精力學更多的語言。。。
以前人們試圖在語言的威力(power)和生產率(productivity)中尋求最佳平衡點,現在似乎更想魚與熊掌兼得。。。
Java的目的是讓一種語言在多種平臺上運行,而C# 的目的是讓多種語言在一種平臺上運行。
兩個平臺語言,一個重在語言,讓語言向平臺擴散;一個重在平臺,讓平臺來凝聚語言。。。
編程語言絕非象牙塔中之物,實乃技術和商業合力推動的結果。。。
C++提供了一馬平川的大路,也提供了陷阱密布的小道;Java則在大路上鋪設水泥,同時封鎖了捷徑小道;C#同樣填平了大路上的坑坑洼洼,但把一些小道上‘此路不通’的牌子偷偷改成了‘此路危險’。
閱讀全文
摘要:
討論C語言 , C++ 和D語言
問號忙問:“您打算比較哪些主流語言呢?”。。。
關于C語言,前面多次提到。這是一把歷久彌新的寶劍,一旦出鞘,依舊寒光逼人,鋒利無儔。有了它,便如戰將有了佩劍,平添一分獨闖敵營的膽氣。。。
能力越大,責任越大,風險越大。此話既適用于編程語言,也適用于程序員。。。
指責C++不是100%OOP的說法更是荒謬之極。OOP又不是金子,含量越高越好。試圖把一切都裝進OOP的箱子里的想法無異于削足適履。。。
C與C++同為系統語言,決定了它們的理念是:優化機器的時間而不是人的時間,優化機器的記憶而不是人的記憶;假設編譯器是愚蠢的而程序員是聰明的,因此賦予程序員更多的權利、義務與責任。。。
C++是匹無轡無鞍的野馬,看似桀驁不馴,若能順性而御,必能足踏飛燕,行千里而不勞。。。
閱讀全文
摘要:
關于編程語言的討論
教室里,學員們正熱火朝天地討論著流行的編程語言。。。
通禪悟道者拈花不語,坐井觀天者蛙鳴鼓噪。。。
如果說編程范式是一種文化,那么編程語言更像是一種宗教——盡管它本不該是。。。
對待一門語言的態度應該是:與其抱怨爭執,不如揚長避短。。。
對一種語言最大的批判是發明一種與此語言有類似功用的新語言;從另一個角度看,發明一種語言也是對先前語言的一種最高的贊美。。。
過分拔高一種語言與抹煞語言之間的差別是兩種極端,皆為秕言謬說。。。
語言為本,余者為末。許多人偏偏本末倒置,常常為在IDE、框架、設計工具等中挖掘到某一新功能而欣喜不已,或者津津樂道于各種語言的優劣高下,卻對正在使用的語言中大量的寶藏視而不見。這些人若有幸拜關公為師,他們最艷羨的一定他的赤兔馬和青龍偃月刀,或許還會抹紅臉蓄長須什么的,就是不太愿學他的蓋世武功。。。
閱讀全文
摘要:
動態語言簡談
嘆號急不可耐地問:“現在可以談動態語言了吧?”
冒號感言:“曾幾何時,動態語言還只是陪太子讀書的角色,那時候它們的名字是‘腳本語言’。近來卻迅速崛起,儼然有與靜態語言分庭抗禮之勢。”。。。
程序是為終端用戶服務的,而腳本是為程序員服務的。。。
動態語言秉承的一個理念是:優化人的時間而不是機器的時間,因此為提高人的生產率而不惜犧牲部分程序的性能。。。
兩類語言的風格的確大相異趣:待靜態語言披盔戴甲、備馬抬槍之際,動態語言已衣袂飄飄,長劍出手了。。。
當腳本語言穿上動態語言的彩衣,昔日不起眼的毛毛蟲便羽化成碟,開始飄舞在眾人追逐的目光之中。但靜態語言也絕不會淡出人們的視線,它如矯健的蒼鷹,依然有搏擊長空的雄力。程序員只要保持嚴謹的作風和開放的心態,既有穩如泰山的馬步,又有一躍凌空的飛腿,靜如處子,動如脫兔,如履平地般游走于高高的梅花樁上,絕無跌落之虞。。。
閱讀全文
摘要:
關于數據類型
待教室平靜下來,冒號再度開腔:“在談論動態語言之前,最好先澄清一下它與動態類型語言之間的區別。”。。。
數據類型既有針對機器的物理意義,又有針對人的邏輯意義。。。
靜態類型檢查類似‘疑罪從有’的有罪推定制——在被證明合法之前是非法的,動態類型檢查類似‘疑罪從無’的無罪推定制——在被證明非法之前是合法的。。。
閱讀全文
摘要:
討論下一步教學計劃
一陣商討之后,眾人似乎未能達成共識。冒號見狀,便讓他們一一道來。。。
網頁的迷人之處就在于,能夠用精美的畫皮來包裹冗長低效的代碼。。。
無論干哪一行,要勝任愉快,離不開四樣東西:才能 、興趣 、方法和努力。沒有才能則難以勝任;沒有興趣則難以愉快;沒有方法則事倍功半;沒有努力則一事無成。。。
閱讀全文
摘要:
編程范式總結
眾人落座之后,冒號開始了第四課的講授:“我們已經涉及了不少編程范式,雖只是走馬觀花,亦可管窺一斑。現用表格歸納如下——”。。。
編程水平的提升之道是:在實戰中演練招法,在招法中領會心法,心法反過來提升招法,進而提高實戰水平,如此循環往復呈螺旋式上升過程。正所謂熟能生巧,巧能生通。。。
軟件工程中有個迭代開發法,本班則采用迭代學習法:即在具體知識與抽象理論之間進行折返式學習。當然這種迭代不是機械式的重復,而是增量式的循環。。。
閱讀全文
摘要:
餐館里的編程范式
嘆號摘下眼鏡,揉了揉眼:“范式再好,多了也難免有些審美疲勞。”
逗號也搓著太陽穴:“現在腦子被灌得沉甸甸的。”
“彼此彼此!你們的腦袋鬧澇災,我的喉嚨鬧旱災。”冒號說著,拿起礦泉水瓶一飲而盡。
大伙聽著怪別扭的,這不是拐著彎說我們腦子進水了嗎?
冒號清了清嗓子:“為尊重民意,也為避免消化不良,大家先放松一下。下面我們來個情景編程。”。。。
閱讀全文
摘要:
AOP簡談
引號重開話題:“OOP方興未艾,AOP又開始嶄露頭角。AOP算是OOP的一種分支、一種補充還是一種超越?”。。。
“準確地說,抽象是前提,分解是方式,模塊化是結果。”冒號很講究精確,“大家記得庖丁解牛的故事吧?在常人眼中復雜的牛體,庖丁經過抽象,已目無全牛,及至提刀分解,自是游刃有余。待牛如土委地,模塊化既成。”。。。
問號提問:“抽象與分解的原則是什么?”
冒號作了個V字:“兩條:單一化,正交化。每個模塊職責明確專一,模塊之間相互獨立,即高聚合低耦合。。。
何謂橫切關注點?顧名思義,乃是與程序的縱向主流執行方向橫向正交的關注焦點。。。
對程序員來說,英語也是一門計算機語言。。。
閱讀全文
摘要:
元編程簡談
引號忽然想起一事,問道:“有一本名為《C++模版元編程》的書,既然提到了模板,想來也屬于泛型編程吧?”。。。
“元程序將程序作為數據來對待,能自我發現和自我賦權,有著其他程序所不具備的自覺性、自適應性和智能性,可以說是一種最高級的程序。它要求編程者超越常規的編程思維,在一種嶄新的高度上理解編程。想象一下,”冒號激情勃發,“如果有一天機器人能自我學習、自我完善,甚至能生產機器人,實現‘智能繁衍’,是不是很美妙?”。。。
閱讀全文
摘要:
泛型式編程簡談
冒號重新開講:“你們會不會經常遇到這種情景:一遍又一遍地寫著相似的代碼,有心將其歸并,卻因種種原因無法踐行。”
逗號心有戚戚焉道:“是啊,有時明明兩個函數的實現幾乎一模一樣的,就因為某些參數不匹配,無法合而為一。”
“有一種編程范式可以解決這個問題,它打破了不同數據結構之間的壁壘,讓你的代碼不再臃腫,這——就是泛型編程。”冒號的語調和說辭不免令人聯想到電視上的減肥廣告。。。
算法串聯數據,如脊貫肉;數據實化算法,如肉附脊。。。
泛型編程是算法導向(Algorithm-Oriented)的,即以算法為起點和中心點,逐漸將其所涉及的數據結構內涵模糊化、外延擴大化,從而擴展算法的適用范圍。。。
在數學家眼里,思想是雞,結論是蛋。。。
閱讀全文
摘要:
并發式編程簡談
逗號好奇地問:“還有其他類型的編程范式嗎?”
“不但有,而且有很多。”冒號喝了一口水,悠悠地說,“并發式編程就是其中之一。”。。。
并發式編程以進程為導向(Process-Oriented),以資源共享與競爭為主線——與當今世界形勢何其相似乃爾!這意味著程序設計將圍繞進程的劃分與調度、進程之間的通訊與同步等等來展開。。。
如果將程序系統視作公司,那么并發式系統是產品型公司,每個進程是一名工人,其職責是執行單一任務;對象式系統是服務型公司,每個對象是一名服務員,其職責是提供系列服務。。。
閱讀全文
摘要:
OOP簡談
短憩之后,引號迫不及待地問:“面向對象的范式應該是一種特殊的命令式吧?”。。。
與其說OOP更具重用性,不如說更具易用性。。。
如果把整個流程看作一顆倒長的大樹,過程式編程自樹根向下,逐漸分支,直到每片樹葉,類似數學證明中的分析法,即執果索因的逆推法;OOP則從每片樹葉開始,逐漸合并,直到樹根,類似數學證明中的綜合法,即執因索果的正推法。。。
函數是被動的實體,對象是主動的實體。過程式程序的世界是君主制的,主函數是國王,其他函數是臣民,等級分明,所有臣民在聽命于上級的同時也對下級發號施令,最終為國王服務;OO程序的世界是民主制的,所有對象都是獨立而平等的公民,有權力保護自己的財產和隱私并向他人尋求服務,同時有義務為他人提供承諾的服務,公民之間通過信息交流來協作完成各種任務。。。
閱讀全文
摘要:
命令式編程與聲明式編程簡介
第二課伊始,冒號開門見山:“首先介紹的是最基本的兩種編程范式:命令式和聲明式,其中命令式又稱過程式。。。”
命令式編程是行動導向(Action-Oriented)的,因而算法是顯性而目標是隱性的;聲明式編程是目標驅動(Goal-Driven)的,因而目標是顯性而算法是隱性的。。。
歸根結底,編程是尋求一種機制,將指定的輸入轉化為指定的輸出。三種范式對此提供了迥然不同的解決方案:命令式把程序看作一個自動機,輸入是初始狀態,輸出是最終狀態,編程就是設計一系列指令,通過自動機執行以完成狀態轉變;函數式把程序看作一個數學函數,輸入是自變量,輸出是因變量,編程就是設計一系列函數,通過表達式變換以完成計算;邏輯式把程序看作一個邏輯證明,輸入是題設,輸出是結論,編程就是設計一系列命題,通過邏輯推理以完成證明。。。
閱讀全文
摘要:
關于框架、設計模式、架構和編程范式的討論
“現在我們具體介紹一下編程范式。”冒號忽然頓住,隱覺一抹失望從眾人臉上掠過,問號更是欲言又止,便鼓勵他開口。
問號略顯遲疑:“您說編程范式是一種心法,那框架、設計模式還有架構呢?”。。。
“自以為懂的未必真的懂,自以為不懂的未必真的不懂。” 冒號玩起了玄學,“有些概念和技術即使背得爛熟,甚至用得爛熟,那也不代表真正掌握;有些概念和技術看起來很新奇,卻不過是新瓶裝舊酒。”。。。
框架與工具包最大的差別在截然相反的設計理念上:庫和工具包是為程序員帶來自由的,框架是為程序員帶來約束的。。。
設計模式是軟件的戰術思想,架構是軟件的戰略決策。。。
知識的學習有幾種方式:一種靠記憶,一種靠練習,一種靠培養。。。
句號悟道:“您是想告訴我們,編程范式就是編程語言的語感?”。。。
閱讀全文
摘要:
關于編程心法
問號第一個從小說里走出來,問道:“剛才談到了低級語言和中級語言,現在該談高級語言了吧?”。。。
掌握一門語言的語法、工具和技巧固然重要,但那只相當于學會一門兵器的招法,更重要的當然是心法。招法重形,心法重意。得形而忘意,無異舍本逐末;得意而忘形,方能游刃有余。下面要談的就是一種心法:編程范式。。。
當你編程之時,便進入到自己創造的世界之中。這是你的世界,只有注入你的想象力、創造力和激情,它才有勃勃生機。你編寫的豈止是代碼,分明還有樂曲;你敲擊的豈止是鍵盤,分明還有琴鍵;你運行的豈止是程序,分明還有世界。當優美的旋律奏起,整個世界都隨之翩然起舞,一種莫可名狀的滿足是否會充溢你的全身?。。。
句號一語驚人:“找對象是‘對象導向’的,去約會是‘面向對象’的。”。。。
閱讀全文
摘要:
簡要回顧計算機語言
問號覺得自己的問題并未解決,追問:“這么多種語言,僅憑流行度就能分出主次優劣嗎?”
“流行度當然不是唯一的指標。”冒號答道,“語言的主次優劣因人而異,答案在你們自己身上。還是剛才那句話,唯一的老師是你自己。”
期待的目光如風中之燭般開始黯淡。。。
好的語言就是適合編程者和解決對象的語言。。。
句號靈光一閃:“我明白了——西門吹雪的西來一劍,那是C語言;李尋歡的小李飛刀,那是匯編語言;陸小鳳的靈犀一指,那是機器語言。”。。。
閱讀全文
摘要:
關于流行計算機語言的討論
眾人面面相覷,一陣沉默后開始竊竊私語,顯然有些不太習慣這種教學方式——筆記本上還沒寫兩個字呢,老師就把球給踢回來了。
冒號也不說話,只是微笑地望著大家。
還是問號打破僵局,開始發問:“老師——”。。。
沒有激情作氧氣,靈感的火花注定轉瞬即滅。。。
閱讀全文
摘要:
程序員提高班之開班發言
冒號開了個程序員提高班,今天迎來了首期學員,他們是問號、句號、逗號、引號和嘆號,皆為IT業的新兵。望著臺下洋溢著青春與渴望的臉龐,冒號開始了他的開班發言——
大家好!先自我介紹一下,本人姓冒名號字解之。。。
本班的宗旨是:學會不如會學,會學不如會用,會用不如被用。。。
如果知識是水,我們要挖掘最先涌動的那顆泉眼;如果知識是火,我們要捕捉起初點燃的那顆火花。。。
閱讀全文