最近可自由安排的時間比較多, iOS應用方面, 沒什麼好點子, 就先放下, 不寫了。花點時間學學設計模式。
之後將會寫一系列博文, 記錄設計模式學習過程。
當然, 因為我自己是搞iOS的, 所以之後設計代碼部分, 將盡量與objective-c相結合。
一。定義
設計模式(Design pattern)是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。
使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。
毫無疑問,
設計模式於己於他人於系統都是多贏的;模式使代碼編制真正工程化;設計模式是軟件工程的基石脈絡,如同大廈的結構一樣。
二。目的
其目的就是一方面教你如何利用真實可靠的設計來組織代碼的模板。 簡單地說,就是從前輩們在程序設計過程中總結、抽象出來的通用優秀經驗。
主要目的一方面是為了增加程序的靈活性、可重用性。
另一方面也有助於程序設計的標准化和提高系統開發進度。
也有人忠告:不要過於注重程序的“設計模式”。 有時候,寫一個簡單的算法,要比引入某種模式更容易。在多數情況下,程序代碼應是簡單易懂,甚至清潔工也能看懂。不過呢, 在大項目或者框架中,沒有設計模式來組織代碼,別人是不易理解的。
一個軟件設計模型也僅僅只是一個引導。它必須根據程序設計語言和你的應用程序的特點和要求而特別的設計。
三。原則
面向對象有幾個原則:
開閉原則(Open Closed Principle,OCP)裡氏代換原則(Liskov Substitution Principle,LSP)依賴倒轉原則(Dependency Inversion Principle,DIP)接口隔離原則(Interface Segregation Principle,ISP)合成/聚合復用原則(Composite/Aggregate Reuse Principle,CARP)最小知識原則(Principle of Least Knowledge,PLK,也叫迪米特法則)
開閉原則具有理想主義的色彩,它是面向對象設計的終極目標。其他幾條,則可以看做是開閉原則的實現方法。
設計模式就是實現了這些原則,從而達到了代碼復用、增加可維護性的目的。
1)開-閉原則( Open - ClosedPrinciple 縮寫:OCP ):對擴展開放,對修改關閉
意思是,在一個系統中,對於擴展是開放的,對於修改是關閉的,一個好的系統是在不修改源代碼的情況下,可以擴展你的功能..而實現開閉原則的關鍵就是抽象化.
通過擴展已有軟件系統,可以提供新的行為,以滿足對軟件的新的需求,使變化中的軟件有一定的適應性和靈活性。已有軟件模塊,特別是最重要的抽象層模塊不能再修改,這使變化中的軟件系統有一定的穩定性和延續性。
在開-閉原則中,不允許修改的是抽象的類或者接口,允許擴展的是具體的實現類,抽象類和接口在開-閉原則中扮演著極其重要的角色..即要預知可能變化的需求.又預見所有可能已知的擴展..所以在這裡抽象化是關鍵!!!
可變性的封閉原則:找到系統的可變因素,將它封裝起來..這是對開-閉原則最好的實現..不要把你的可變因素放在多個類中,或者散落在程序的各個角落..你應該將可變的因素,封套起來..並且切忌不要把所用的可變因素封套在一起..最好的解決辦法是,分塊封套你的可變因素!!避免超大類,超長類,超長方法的出現!!給你的程序增加藝術氣息,將程序藝術化是我們的目標!!
2) 裡氏代換原則:任何基類可以出現的地方,子類也可以出現
Liskov Substitution Principle(裡氏代換原則):子類能夠必須能夠替換基類能夠從出現的地方。子類也能在基類 的基礎上新增行為。這yi講的是基類和子類的關系,只有這種關系存在時,裡氏代換原則才存在。正方形是長方形是理解裡氏代換原則的經典例子。
3) 依賴倒轉原則::要依賴抽象,而不要依賴具體的實現.
依賴倒置(Dependence Inversion Principle)原則講的是:要依賴於抽象,不要依賴於具體。簡單的說,依賴倒置原則要求客戶端依賴於抽象耦合。原則表述:
(1)抽象不應當依賴於細節;細節應當依賴於抽象;
(2)要針對接口編程,不針對實現編程。
如果說開閉原則是目標,依賴倒轉原則是到達開閉原則的手段..如果要達到最好的開閉原則,就要盡量的遵守依賴倒轉原則..可以說依賴倒轉原則是對抽象化的最好規范!!我個人感覺,依賴倒轉原則也是裡氏代換原則的補充..你理解了裡氏代換原則,再來理解依賴倒轉原則應該是很容易的..
4)合成/聚合復用原則(CARP):要盡量使用合成/聚合原則,而不是繼承關系達到軟件復用的目的
合成/聚合復用原則(Composite/Aggregate ReusePrinciple或CARP)經常又叫做合成復用原則(Composite ReusePrinciple或CRP),就是在一個新的對象裡面使用一些已有的對象,使之成為新對象的一部分;新對象通過向這些對象的委派達到復用已有功能的目的。簡而言之,要盡量使用合成/聚合,盡量不要使用繼承。
要盡量使用合成/聚合原則,而不是繼承關系達到軟件復用的目的。此原則和裡氏代換原則氏相輔相成的,兩者都是具體實現開-閉原則的規范..違反這一原則:就無法實現開-閉原則..先來看看什麼是合成,什麼是聚合.
什麼是合成?
合成:是指一個整體對依托他而存在的關系,例如:一個人對他的房子和家具,其中他的房子和家具是不能被共享的,因為那些東西都是他自己的..並且人沒了,這個也關系就沒了..這個例子就好像,烏雞百鳳丸這個產品,它是有烏雞和上等藥材合成而來的一樣..也比如網絡游戲中的武器裝備合成一樣,多種東西合並為一種超強的東西一樣..
什麼是聚合?
聚合:聚合是比合成關系的一種更強的依賴關系,聚合是一個整體對個體的部分,例如,一個奔馳S360汽車,對奔馳S360引擎,奔馳S360輪胎的關系..這些關系就是帶有聚合性質的..因為奔馳S360引擎和奔馳S360輪胎他們只能被奔馳S360汽車所用,離開了奔馳S360汽車,它們就失去了存在的意義..在我們的設計中,這樣的關系不應該頻繁出現..這樣會增大設計的耦合度..
明白了合成和聚合關系,再來理解合成/聚合原則應該就清楚了..要避免在系統設計中出現,一個類的繼承層次超過3次..如果這樣的話,可以考慮重構你的代碼,或者重新設計結構..當然最好的辦法就是考慮使用合成/聚合原則...
5)迪米特法則:系統中的類,盡量不要與其他類互相作用,減少類之間的耦合度
迪米特法則(Law of Demeter或簡寫LoD)又叫最少知識原則(Least Knowledge Principle或簡寫為LKP),也就是說,一個對象應當對其它對象有盡可能少的了解。
其它表述:只與你直接的朋友們通信,不要跟陌生人說話。一個類應該對自己需要耦合或調用的類知道得最少,你(被耦合或調用的類)的內部是如何復雜都和我沒關系,那是你的事情,我就知道你提供的public方法,我就調用這麼多,其他的一概不關心。
迪米特法則與設計模式Facade模式、Mediator模式使民無知
系統中的類,盡量不要與其他類互相作用,減少類之間的耦合度,因為在你的系統中,擴展的時候,你可能需要修改這些類,而類與類之間的關系,決定了修改的復雜度,相互作用越多,則修改難度就越大,反之,如果相互作用的越小,則修改起來的難度就越小..例如A類依賴B類,則B類依賴C類,當你在修改A類的時候,你要考慮B類是否會受到影響,而B類的影響是否又會影響到C類..如果此時C類再依賴D類的話,呵呵,我想這樣的修改有的受了..
6)接口隔離法則:這個法則與迪米特法則是相通的
接口隔離原則(Interface Segregation Principle)講的是:使用多個專門的接口比使用單一的總接口總要好。換而言之,從一個客戶類的角度來講:一個類對另外一個類的依賴性應當是建立在最小接口上的。
過於臃腫的接口是對接口的污染。不應該強迫客戶依賴於它們不用的方法。
迪米特法則是目的,而接口隔離法則是對迪米特法則的規范..為了做到盡可能小的耦合性,我們需要使用接口來規范類,用接口來約束類.要達到迪米特法則的要求,最好就是實現接口隔離法則,實現接口隔離法則,你也就滿足了迪米特法則...
四。分類
設計模式分為三種類型,共23種。
創建型模式:單例模式、抽象工廠模式、建造者模式、工廠模式、原型模式。結構型模式:適配器模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式。行為型模式:模版方法模式、命令模式、迭代器模式、觀察者模式、中介者模式、備忘錄模式、解釋器模式、狀態模式、策略模式、職責鏈模式、訪問者模式。按字典序排列簡介如下。
Abstract Factory(抽象工廠模式):提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。Adapter(適配器模式):將一個類的接口轉換成客戶希望的另外一個接口。Adapter模式使得原本由於接口不兼容而不能一起工作的那些類可以一起工作。Bridge(橋接模式):將抽象部分與它的實現部分分離,使它們都可以獨立地變化。Builder(建造者模式):將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。Chain of Responsibility(職責鏈模式):為解除請求的發送者和接收者之間耦合,而使多個對象都有機會處理這個請求。將這些對象連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個對象處理它。Command(命令模式):將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日志,以及支持可取消的操作。Composite(組合模式):將對象組合成樹形結構以表示“部分-整體”的層次結構。它使得客戶對單個對象和復合對象的使用具有一致性。Decorator(裝飾模式):動態地給一個對象添加一些額外的職責。就擴展功能而言, 它比生成子類方式更為靈活。Facade(外觀模式):為子系統中的一組接口提供一個一致的界面,Facade模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。Factory Method(工廠模式):定義一個用於創建對象的接口,讓子類決定將哪一個類實例化。Factory Method使一個類的實例化延遲到其子類。Flyweight(享元模式):運用共享技術有效地支持大量細粒度的對象。Interpreter(解析器模式):給定一個語言, 定義它的文法的一種表示,並定義一個解釋器, 該解釋器使用該表示來解釋語言中的句子。Iterator(迭代器模式):提供一種方法順序訪問一個聚合對象中各個元素,而又不需暴露該對象的內部表示。Mediator(中介模式):用一個中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。Memento(備忘錄模式):在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。這樣以後就可將該對象恢復到保存的狀態。Observer(觀察者模式):定義對象間的一種一對多的依賴關系,以便當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並自動刷新。Prototype(原型模式):用原型實例指定創建對象的種類,並且通過拷貝這個原型來創建新的對象。Proxy(代理模式):為其他對象提供一個代理以控制對這個對象的訪問。Singleton(單例模式):保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。 單例模式是最簡單的設計模式之一,但是對於Java的開發者來說,它卻有很多缺陷。在九月的專欄中,David Geary探討了單例模式以及在面對多線程(multi-threading)、類裝載器(class loaders)和序列化(serialization)時如何處理這些缺陷。State(狀態模式):允許一個對象在其內部狀態改變時改變它的行為。對象看起來似乎修改了它所屬的類。Strategy(策略模式):定義一系列的算法,把它們一個個封裝起來, 並且使它們可相互替換。本模式使得算法的變化可獨立於使用它的客戶。Template Method(模板方法模式):定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。Template Method使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。Visitor(訪問者模式):表示一個作用於某對象結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。
雖然這篇文章看起來比較頭大, 都是文字。但它確實是學習設計模式需要了解的一些的。
當然, 我這裡的資料也是從網上copy來的。 摘錄了一些我覺得有必要了解的。
對於這些知識, 看著理解就好了。
學習的路上, 與君共勉