前言
《設計模式》這本經典的書里面定義了20多種設計模式,雖然都是面向對象的,似乎需要C++、Java這樣的語言才能實現,但是根據筆者前面反復強調的,Linux內核雖然是用C語言和匯編語言寫成,但是其實也到處充滿了面向對象的設計。面向對象更多的是一種思想,而不是一個語言。我們可以用C語言實現極大的OO,Linux內核到處都有OO。
模板方法
比如,在Linux的設備驅動框架中,就用了一種非常經典簡單的設計模式——模板方法(Template Method),當然還有一些其他的設計模式。而設計模式牛逼的地方在于,高手往往不經意之間已經用到了設計模式,甚至自己都不知道。如果高手沒有系統地學習過設計模式,這其實不見得是一個問題。這并不意味著它不懂設計模式,只是他自己都不知道自己用到了哪個模式。而設計模式學習的終極目的,當然也是忘記設計模式,這個跟練獨孤九劍沒什么區別,到最后其實是無招勝有招。
模板方法這個模式,強調定義一個基類,這個基類實現了通用的流程和算法。比如做一件事情需要經過step1()、step2()、step3()。那么我們定義一個基類:
而其中的step1()、step2()、step3()、step4()具體如何實現則是因人而異,所以我們從baseClass類里面,繼承出來的類里面,實現step1()、step2()、step3()這樣的代碼,override掉baseClass里面的函數。
這樣的設計讓外部不關心derivedClass,因為流程和接口都是在基類的。而基類實現的doSomething()成員函數,是對外的接口。這個UML關系是非常簡單的:
驅動案例
在Linux設備驅動里面,大量存在類似的設計,我們以NAND為例子。在drivers/mtd/nand/nand_base.c這層里面,定義了NAND的一些操作流程。
比如寫OOB的代碼:
它這個里面要走cmdfunc()、write_buf()、cmdfunc()、waitfunc()這些步驟,這些步驟,不管是全世界哪個NAND的硬件,都是一樣的通用的,但是具體的不同的NAND硬件控制器,實現這些步驟中涉及到的cmdfunc()等函數的實現方法卻因人而異。
譬如freescale的版本fsl_elbc_nand.c就是:
nand_base.c這個C文件是NAND的中間層,它非常類似我們前面說的實現baseClass這一層的代碼,nand_write_oob_std函數類似baseClass :: doSomething。而Linux驅動中定義的nand_chip的各個不同的NAND控制器,對nand_chip這個結構體中成員函數cmdfunc()、write_buf()等的實現則是各異的,類似derivedClass里面override掉step1()、step2()。nand_chip定義在include/linux/mtd/nand.h:
這樣的設計,好處是非常明顯的。特定的硬件只用管與自身操作相關的事情,而通用的流程,都由nand_base搞定,最大程度上減小了具體實例的代碼量,也最大程度上復用了中間層的代碼。
這樣的例子無處不在,比如我們在LCD的中間層:
后語
本文后語不搭前言,請見諒。最近有很多童鞋詢問筆者,做Linux驅動有沒有前途?筆者明確地告訴大家:根本沒有前途!但是前途是自己賺的,這依賴你從驅動進去,但是從更大的視角出來:
1.通過做驅動理解很多OO的架構設計思想,升華自己高內聚和低耦合的理解,把自己變成一個更高level的software engineer;
2.通過做驅動,進一步理解Linux本身的進程、內存、IO等知識,升華對軟件系統和性能分析的理解,把自己變成一個更高level的技術expert。
如果做了5年驅動,進入的時候是調試寄存器搞示波器,出來的時候還是調寄存器搞示波器,那自然是完全沒有什么前途的!
有沒有前途,這個事情,完全是因人而異的。前途是無所謂有,無所謂無的。你如果有抽象、衍生的能力和不斷學習總結的精神,無論是做驅動還是不做驅動,都會是很有前途的事情。反之,做什么基本都沒前途。
-
Linux
+關注
關注
87文章
11320瀏覽量
209849 -
C語言
+關注
關注
180文章
7608瀏覽量
137126
原文標題:宋寶華:Linux設備驅動框架里的設計模式之——模板方法(Template Method)
文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論