設計模式之我見(一)

說道設計模式,仍是當初入行沒多久看的,記得當初看的是秦小波的《設計模式之禪》。起初不明白這個爲何要字一個禪字。直到看了第三遍才明白,就算是同一我的也會由於經驗和知識增加獲得不一樣的結論。最近在重構以前的代碼,剛好有用到設計模式,因此就準備重寫回顧一下,記錄一些如今的我的看法和實際工做中的體會。按實際開發實際我仍是個不足2年經驗的小猿,如有考慮不周,還請見諒!
要說設計模式,那就離不開六點設計原則。那麼就從設計原則講起。
1、單一原則。
單一原則這個原則有不少爭議,它講的是一個類要控制其粒度大小,規定一個類應該只有一個發生變化的緣由,也就是一個類要儘可能只負責一件事情(我的感受在實際開發中,好多類都沒有嚴格遵照這一原則,或者說很難作到這樣)。爲何要這樣呢,我講一個工做中遇到的反面例子,在以前的公司作數據處理,根據客戶的要求要根據不一樣來源的數據作不一樣的映射,映射大致方式相似。因而爲了方便你們開發便絞盡腦汁封裝了一個公共處理類供你們使用。開始項目初期數據來源少,並無發生什麼問題,你們也很滿意,(你們注意轉折來了)可是隨着項目的推動,數據來源愈來愈多,隨之而來的數據映射方式也愈來愈多。爲了適應各類映射方式你們開始在公共類中加入一些能夠覆寫的空方法,用子類繼承公共類覆寫某些方法來實現改變(模板設計模式)。後來就算這樣也沒法解決映射邏輯的不一樣,除非覆寫主要的映射邏輯方法,這樣和重寫一個類沒什麼區別。因而有人開始修改原始公共邏輯來適配本身的映射。這一改各類莫名其妙的bug接踵而至,把搞得你們焦頭爛額。這件事讓我明白,一個類承擔的責任相對單一,那它被改動的機率和範圍就越小,那這個類出現問題的機率就越小。這也許就是單一原則的指望之一吧。java


2、里氏替換原則。
在面嚮對象語言中有一種機制叫作繼承,繼承的優勢必我來講了吧,好比代碼複用啊,提升代碼的可擴展性啊,現實多態啊等等。缺點也不言而喻繼承是入侵性質的代碼耦合過高。而里氏替換法則要說的就是隻要父類能出現的地方,子類就能夠出現而且替代父類正確的運行。可是反過來卻不行,也就是說應該是子類的地方,父類未必能給運行。《設計模式之禪》一書中說道:里氏替換法則爲良好的繼承定義了一個規範,一句簡單的定義包含了4層含義。編程

  1.子類必須徹底實現父類。舉一個很簡單的栗子,我有寫過一個對json串進行排序和比較地小工具,我在裏面寫了一個預處理json串的類,他要作的工做就是預先處理下json串,好比去掉首位大括號前的一些莫名其妙的字符和去掉轉譯符,忽然有一天我發現它已經不能勝任我新的需求了可是我又不打算改變之前的代碼,由於這樣會形成不少奇怪的問題第一點中已經提到過了。因此我打算寫個類繼承這個處理類,而後用新的其子類來代替父類對json串進行處理。可是由於疏忽,我忘記在新的子類中調用父類的方法,這就給本身挖了一個巨坑,若是別人輸入的json串包含轉譯符或者首尾大括號先後有奇奇怪怪的字符就會致使程序解析json時報錯,沒法獲得預期結果。json

  2.子類能夠有本身的個性。通俗來說那就是子類是父類的拓展,能夠完成一些父類作不到的事情。打比方你有一個父類是Birds(鳥類),這個類中有一個方法叫作flight(飛行),你能夠寫一個子類Swan(天鵝), 天鵝是鳥類因此它繼承自Birds擁有飛行方法,可是天鵝也有本身獨特的地方它會游泳,因此它也有本身有的方法Swimming(游泳)。設計模式

  3.覆蓋或實現父類的方法時輸入參數必須等於或者大於父類方法的參數。關於這點是由於java本身重載緣由。決定一個方法是不是同一個方法的判斷條件是方法名和入參。若是入參改變了的話編譯器認爲是重載方法而不是覆寫。所以當子類被當作父類傳入時,調用的方法依舊仍是父類的方法,並不能達到預期的效果。工具

  4.覆寫或者實現父類方法時輸出結果能夠相等或者縮小(這點若是是變大是通不過編譯的)。設計


3、依賴倒置原則。
定義:模塊之間的依賴,都應該依賴對方的抽象接口,而不發生實現的直接依賴,而且實現應該依賴抽象接口。這個相信你們在平常使用中應該常常用到。說的簡單點就是面向接口編程,就拿運行遊戲來講吧,你有一臺遊戲主機,它有一個方法叫作function(運行),這個方法接受一個參數遊戲。假設咱們如今固定傳入的參數寫的是實現類好比XX遊戲,那下次若是出現了新的YY遊戲,你的主機的運行方法居然沒法接受並運行它這明顯是不合理的。也許你會說,那再加一個方法唄,入參寫上YY遊戲。若是這樣那是否是每發行一個遊戲,主機就要寫一個方法,而且編譯安裝一次這是否是太麻煩了也大大增長了系統的不穩定性(你每發佈一個遊戲就要修改一次系統,這樣的系統能穩定嗎?)。爲何會形成這樣的結果,其緣由是由於兩個模塊以前互相依賴的是實現類,耦合太過緊密,若是一個發生變化那另外一個也要爲這個改變作出適配。如何解決這個問題,那就是上面談到的面向接口編程。接口就是一個契約,全部的遊戲廠商和主機生產商坐在一塊兒商量下,定個規範,好比遊戲接口,規定遊戲應該怎麼怎運行。全部的遊戲廠商就按這個契約開發,主機廠商也按這個契約來進行系統開發和適配。這樣就皆大歡喜,只是要按這個規範來開發的遊戲就能夠運行在全部的主機上,而按這個規範開發的主機也能夠運行全部該規範下的遊戲。皆大歡喜,你們都不要爲這個適配作重複的工做,世界也變得美好了,咱們也不用加班了。多好。對象

相關文章
相關標籤/搜索