本文系轉載化漆,著作權歸作者所有苗缩。商業(yè)轉載請聯(lián)系作者獲得授權病游,非商業(yè)轉載請注明出處侨拦。
作者: 宋寶華
來源: 微信公眾號linux閱碼場(id: linuxdev)
前言
《設計模式》這本經(jīng)典的書里面定義了20多種設計模式,雖然都是面向對象的赠幕,似乎需要C++俄精、Java這樣的語言才能實現(xiàn),但是根據(jù)筆者前面反復強調(diào)的榕堰,Linux內(nèi)核雖然是用C語言和匯編語言寫成竖慧,但是其實也到處充滿了面向對象的設計。面向對象更多的是一種思想逆屡,而不是一個語言圾旨。我們可以用C語言實現(xiàn)極大的OO,Linux內(nèi)核到處都有OO魏蔗。
模版方法
比如砍的,在Linux的設備驅動框架中,就用了一種非常經(jīng)典簡單的設計模式——模板方法(Template Method)莺治,當然還有一些其他的設計模式廓鞠。而設計模式牛逼的地方在于,高手往往不經(jīng)意之間已經(jīng)用到了設計模式谣旁,甚至自己都不知道床佳。如果高手沒有系統(tǒng)地學習過設計模式,這其實不見得是一個問題榄审。這并不意味著它不懂設計模式夕土,只是他自己都不知道自己用到了哪個模式。而設計模式學習的終極目的瘟判,當然也是忘記設計模式,這個跟練獨孤九劍沒什么區(qū)別角溃,到最后其實是無招勝有招拷获。
模板方法這個模式,強調(diào)定義一個基類减细,這個基類實現(xiàn)了通用的流程和算法匆瓜。比如做一件事情需要經(jīng)過step1()、step2()未蝌、step3()驮吱。那么我們定義一個基類:
而其中的step1()、step2()萧吠、step3()左冬、step4()具體如何實現(xiàn)則是因人而異,所以我們從baseClass類里面纸型,繼承出來的類里面拇砰,實現(xiàn)step1()梅忌、step2()、step3()這樣的代碼除破,override掉baseClass里面的函數(shù)牧氮。
這樣的設計讓外部不關心derivedClass,因為流程和接口都是在基類的瑰枫。而基類實現(xiàn)的doSomething()成員函數(shù)踱葛,是對外的接口。這個UML關系是非常簡單的:
驅動案例
在Linux設備驅動里面光坝,大量存在類似的設計尸诽,我們以NAND為例子。在drivers/mtd/nand/nand_base.c這層里面教馆,定義了NAND的一些操作流程逊谋。
比如寫OOB的代碼:
它這個里面要走cmdfunc()、write_buf()土铺、cmdfunc()胶滋、waitfunc()這些步驟,這些步驟悲敷,不管是全世界哪個NAND的硬件究恤,都是一樣的通用的,但是具體的不同的NAND硬件控制器后德,實現(xiàn)這些步驟中涉及到的cmdfunc()等函數(shù)的實現(xiàn)方法卻因人而異部宿。
譬如freescale的版本fsl_elbc_nand.c就是:
nand_base.c這個C文件是NAND的中間層,它非常類似我們前面說的實現(xiàn)baseClass這一層的代碼瓢湃,nand_write_oob_std函數(shù)類似baseClass :: doSomething理张。而Linux驅動中定義的nand_chip的各個不同的NAND控制器,對nand_chip這個結構體中成員函數(shù)cmdfunc()绵患、write_buf()等的實現(xiàn)則是各異的雾叭,類似derivedClass里面override掉step1()、step2()落蝙。nand_chip定義在include/linux/mtd/nand.h:
這樣的設計织狐,好處是非常明顯的。特定的硬件只用管與自身操作相關的事情筏勒,而通用的流程移迫,都由nand_base搞定,最大程度上減小了具體實例的代碼量管行,也最大程度上復用了中間層的代碼厨埋。
這樣的例子無處不在,比如我們在LCD的中間層:
后語
本文后語不搭前言捐顷,請見諒揽咕。最近有很多童鞋詢問筆者悲酷,做Linux驅動有沒有前途?筆者明確地告訴大家:根本沒有前途亲善!但是前途是自己賺的设易,這依賴你從驅動進去,但是從更大的視角出來:
通過做驅動理解很多OO的架構設計思想蛹头,升華自己高內(nèi)聚和低耦合的理解顿肺,把自己變成一個更高level的software engineer;
通過做驅動渣蜗,進一步理解Linux本身的進程屠尊、內(nèi)存、IO等知識耕拷,升華對軟件系統(tǒng)和性能分析的理解讼昆,把自己變成一個更高level的技術expert。
如果做了5年驅動骚烧,進入的時候是調(diào)試寄存器搞示波器浸赫,出來的時候還是調(diào)寄存器搞示波器,那自然是完全沒有什么前途的赃绊!
有沒有前途既峡,這個事情,完全是因人而異的碧查。前途是無所謂有运敢,無所謂無的。你如果有抽象忠售、衍生的能力和不斷學習總結的精神传惠,無論是做驅動還是不做驅動,都會是很有前途的事情稻扬。反之涉枫,做什么基本都沒前途。
更多精彩更新中……歡迎關注微信公眾號:linux閱碼場(id: linuxdev)