今天業務完成到一定程度,查看下代碼,猛然發現目前的這個代碼有點奇怪。奇怪就奇怪在我的model中有很多文件,每個文件都對應數據庫中的一張表,然后每個model中有很多是幾乎沒有什么邏輯代碼的。比如:
這個原因是什么呢,因為rdb_model這個類實現了ORM,我繼承這個類才能使用ORM的那些操作。
但是這個確實讓我很不爽,一個神馬東西都沒有的類為什么要寫呢?引申出的一個問題是到底是胖model好呢,還是瘦model好?
不難想象我項目中的代碼算是胖controller,瘦model了。即我的model完成了ORM的封裝流程,為的就是controller中能更方便使用。說實話,這樣controller中的函數寫下來是非常舒服的。但是考慮一個問題,這樣子是不是違反了DRY原則呢?如果是瘦到只封裝ORM的model,那么一定可以閉着眼睛說,controller中一定有很多會冗余的代碼。這確實是不好的做法。controller中的冗余可共用的代碼並沒有抽象出來,這當然會造成日后的代碼困擾。
那我們退一步,如果model不再那么瘦呢?我們把基礎的一些方法都放到model中,但是我們還是堅守着一個表一個model的方法。那么就會將下面這樣的方法放到model中:
問題就是,這里勢必要使用comment_model了,這個model是comment表的映射,它的內部卻是任何功能都沒有實現。
如果你會說這樣其實沒有什么問題,那么下面問題來了,現在訪問量上來了,我們不從DB中取出數據了,我們改成從DB中取出數據,存入緩存,然后下次再去緩存中取數據。這時候的問題來了,緩存是加在controller中還是model中呢?
這個觀點各執己見,從領域驅動模型來說,緩存是不屬於領域模型范疇的,它和領域數據邏輯沒有關系,它屬於應用層范疇。但是從MVC觀點來看,Model層是數據獲取的抽象,controller層只管理數據的重新組織和連接,數據從哪里來並不屬於controller管理范疇。所以呢,數據從DB中來還是從Cache中來,這是Model層應該管理的。
如果再退一步呢?所有的數據邏輯都寫在model中呢?那么就會出現下面這個看起來奇怪的代碼了:
一個方法只有一行!!如果增刪改查都這么做,就很冗余了。這么多本來可以不用寫的代碼總是讓人非常不爽。在調用的時候反正都是一句話的事情,為什么還要封裝一層呢?
我想所有的分歧先要弄清的是MVC的model是什么的抽象?如果說model是數據結構的抽象,那么ORM就已經完成了這個抽象行為,一個DB一個model就是實現這樣的抽象。但是我覺得並不是這樣的。model應該是業務邏輯上的抽象。就是說,model層應該是觸及到了具體的業務邏輯,它把業務邏輯封裝成了可以給controller調用和使用的語言。這就非常符合領域驅動設計的意思了。model層是將業務領域封裝成模型的層。算是一種“翻譯”工作,將現實中的業務“翻譯”成程序語言。這樣的model封裝才有意義。
然后回到緩存放在controller還是model的觀點。我認為,業務領域獲取數據是從緩存還是DB中獲取,這個邏輯應該是放在model中的,因為這個也屬於“翻譯”的過程。如果這個邏輯由應用層來做的話,它就需要關心到這個訪問和那個訪問是不是同時都使用了緩存,返回的數據是不是一致的這樣一致性問題。那么就是把這層和實際的“運行環境”的邏輯放在本該很清晰的應用層來做了。
但是呢?老子說的,不同情況不同分析。
做前台和做后台是一樣的邏輯嗎?這里說的前台是指API,WEB,WAP等方式。后台指的是運營,審核等后台。我的觀點就是前台盡可能或者強制性地“胖model”化。意思就是所有可以零散放在model中的訪問都在model中放着。這個觀點就默認了
這樣的寫法在前台是合理的。如果在cars這個表上面加個緩存,那么只需要修改model中的三個方法,不需要修改業務的應用邏輯!!這樣就把模型在具體環境的實現完全抽象化了。
但是對於后台呢?后台實際上是對實際數據的強行干預了。所以我們在后台很少觸碰到緩存等優化機制的。並且鑒於后台開發不需要承擔大並發的需求,也往往開發時間緊張於前台。所以后台開發這種“胖controller,瘦model”的模型非常適合的。甚至於能用到“胖controller,無model”我認為也不算過分。
所以再次舉起具體問題具體分析的大旗,這個問題算是有結論了。



