《Object-C程式設計之道》個人感覺是非常好的一本iOS設計模式書籍。
裡面會結合在iOS的Cocoa 框架中使用到的例子進行講解,在學習設計模式的同時,也能對Cocoa框架中使用的設計模式有個熟悉。這一點我非常喜歡。
按照設計模式的功能進行劃分,可以分為八類:
介面適配類,物件去耦類,物件建立類,抽象集合類,物件狀態類,行為擴充套件類,演算法封裝類,效能與物件訪問類。其中包含內容如下:
物件建立型:1.原型模式;2.工廠模式;3.抽象工廠模式;4.單例模式;5.生成器
介面適配型:1.介面卡模式;2.橋接模式;3.外觀模式
物件去耦型:1.中介者模式;2.觀察者模式
抽象集合型:1.組合模式;2.迭代器模式
行為擴充套件型:1.訪問者模式;2.裝飾器模式;3.責任鏈模式
演算法封裝型:1.模版方法模式;2.策略模式;3.命令模式
效能與物件訪問型:1.享元模式;2.代理模式
物件狀態型:1.備忘錄模式
下面將對書中講解到的設計模式進行簡述。
建議有時間的同學去通讀和練習一遍。沒有時間的同學就看我下面寫的吧,先做到心裡有個概況。等有時間了再去研究。
後面計劃對裡面的每種設計模式進行詳解(二十一種,真不少),想持續關注的要留心了。
物件建立型
原型模式:
簡單的說就是複製,用同一個磨具複製出一系列的東西。
使用場景有:
1.建立一個例項流暢複雜,複製比較容易;
2.建立一個物件子物件組合比較多,複製比較容易;
應用例項:
自定義物件實現NSCopy協議或者NSMutableCopy協議,實現方法copyWithZone或者mutableCopyWithZone。就是對此設計模式的體現。
工廠模式:
簡單的說就是在一個類中根據需求,可以生產出多種型別的產品。
使用場景有:
類有很多具體的子類,想讓返回什麼樣的子類區域性化,由內部自行判斷。
應用例項:
NSNumber類定義了一系列的工廠方法:
根據int 生產 intNumber; 根據unsigned int 生產 unsignedNumber;
+ (NSNumber *)numberWithInt:(int)value; + (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
抽象工廠模式:
從產品的角度看,是一種二維的思考。如水果工廠的工廠模式是生產蘋果,橘子。
而蘋果分為北方工廠產的蘋果,南方工廠產的蘋果。
從工廠的角度看,比較簡單。抽象工廠下面兩個子工廠,它們都可以生產蘋果,橘子。
應用例項:
NSNumber抽象工廠。下面很多具體的number工廠,如:
+ (NSNumber *)numberWithInt:(int)value; + (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
單例模式:
一個類只有一個例項,並提供全域性訪問點。
使用場景有:
系統只能共享,無法複製的元素。
應用例項:
檔案系統管理類:整個系統只有一份。
UIApplication:一個App只有一個應用單例。
生成器模式:
將一個複雜物件的構建與它的表現分離,使得同樣的構建過程可以建立不一樣的表現物件。
使用場景:
構建過程需要用不同的組合構建不同表現的物件。
對於生成一個比較複雜的物件,通常使用生成器模式 裡面按照角色劃分有4種:
客戶端,提出一系列需要,需要什麼樣的產品。
指揮者,從客戶端那裡接收到一系列需要,然後按照功能分割。
構建者,從指揮者手中得到一個需求,並生產一個對於的產品。
物件建立型整體巨集觀圖如下:
介面適配型
介面卡模式:
物件呼叫介面 -> 介面卡 -> 被適配介面,介面卡可以使原本不相容的介面可以一起協調工作了。
使用場景:
已有類的介面與需求類介面不匹配。
應用例項:
Delegate是CocoaTouch框架中採用介面卡模式(委託)的一種實現。實現協議的具體類是個介面卡。
橋接模式:
把抽象層次結構從實現中分離出來,使其能夠獨立變更。
抽象層定義了供客戶端使用的上層抽象介面。
實現層次結構定義了供抽象層次使用的底層介面。
不想在抽象與其實現之間形成固定的繫結關係;
客戶端抽象層引用著實現層抽象層;
外觀模式:
為子系統中一組不同的功能介面,提供統一的外觀服務介面。
子系統變的越來越複雜,可以使用外觀類為這個子系統提供一個簡單的入口。
介面適配型整體巨集觀圖如下:
物件去耦型
中介者模式
一句看概述:封裝物件間的互動。
中介者模式用於定義一個集中的場所,物件間的互動可以在一箇中介者物件內處理, 從而避免其他物件間的依存關係。
使用場景:
物件間的互動定義明確而複雜,導致一組物件彼此互相依賴且難以理解。
使用例項:
元件化開發中使用的路由器,就是一個利用反射機制實現的中介者。
觀察者模式
定義一種一對多的關係,使一個物件狀態改變,所以觀察者物件都收到通知。
觀察者模式也叫釋出-訂閱機制。
可以利用Observer模式,令通知中心為中介,可以做到一個自定義物件通過通知中心 去通知到其他多個物件的目的。
使用場景:
在MVC框架模式中,通過觀察著,實現Model,View的聯動。
物件去耦型整體巨集觀圖如下:
抽象集合型
組合模式
組合模式讓我們把相同基型別的物件組合到樹狀結構中,其中父節點包含同型別的子節點。
元件節點和葉子節點都是實現同一個基類介面。同一個抽象父類。
對組合物件的查詢,訪問都是遞迴操作。
將物件組合成樹形結構,以表示“整體-部分”的層次結構,組合使得使用者對單個物件和組合物件的操作具有一致性。
使用例項:
UIView的樹形結構,包含很多子View。
事件訊息鏈,響應鏈傳遞。
迭代器模式
迭代器提供了一種 順序訪問聚合物件(集合)中元素的方法,而無需暴露結構的底層表示和結構細節。 遍歷集合元素的任務從集合 轉移給了迭代器物件。
使用場景:
需要訪問組合物件內容,而不想暴露內部表示,結構。
迭代器分為內部迭代器和外部迭代器。
外部迭代器允許客戶端更自由的使用,同時需要熟悉組合物件的內部結構。
內部迭代器被封裝在集合內部,在集合外部提供介面。
使用例項:
集合物件(nsarray, nsdictionary)都預設提供了迭代器。
抽象集合型整體巨集觀圖如下:
行為擴充套件型
訪問者模式
作用於組合物件結構中的每一個元素的操作,它讓我們在不改變元素類的前提下,擴充套件這些類的新操作。
在接受訪問者的介面方法中,實現將元素傳給訪問者,然後訪問者擴充套件對元素的操作。
使用場景:
想對一個物件進行很多不相關的操作,又不想汙染這個物件。
裝飾器模式
向物件新增行為而不破壞其原有的風格,因此增強了的物件是同一個類的加強版。任何“增強”均可以動態新增和刪除。裝飾物件可以附加到另一裝飾物件,也可以附加到原始物件。
使用場景:
在不影響物件的情況下,動態,透明的給單個物件新增職責。
使用例項:
濾鏡操作,可以不管濾鏡順序。
責任鏈模式
讓一組物件處理特定的請求,而對這個組中的成員(處理程式物件handler)增加,刪除不影響組的完整性。
鏈中的每一個物件實現了同樣的方法,處理對鏈中第一個物件發起的同一個請求。 如果一個物件不知道如何處理這個請求,就把請求傳給下一個響應器(successor)。
使用場景:
向一組物件傳送處理請求,而不想顯示的指定是哪個物件進行處理。
行為擴充套件型整體巨集觀圖如下:
演算法封裝型
模版方法模式
在抽象父類中定義操作架構和公共操作,具體操作延遲到子類中實現。
在模版方法模式中,使子類可以重定義演算法的某些特定步驟而不改變演算法結構。
使用場景:
需要一次性將不變部分寫好,將可變部分留給子類實現。
使用例項:
在UIView 中的方法draw:(CGRect)rect方法。
這個繪圖方法draw:為UIView提供的鉤子函式,當使用者想要自己繪圖時,就可以自己擴充套件新增。不實現也不影響功能。
策略模式
在物件導向設計中,將不同的演算法分離成不同的類,稱為策略。與這種做法相關的設計模式,稱為策略模式。
使用場景:
在平時的函式中會出現if-else或者switch-case這樣的選擇語句,它們的不同分支下對應的是不同的演算法。 而將這些不同的演算法封裝成一個個不同的演算法物件。實際上就是不同的策略。
使用例項:
控制器是檢視的策略類,檢視可以因為控制器不同而展示不同的資訊。
命令模式
在物件導向設計中,把指令封裝在各種命令物件中,命令物件可以被傳遞, 並且在指定時刻被不同客戶的複用,從這一概念精心設計的模式被稱為命令模式。
使用場景:
想讓程式支援撤銷恢復功能
使用例項:
NSInvocation, NSUndoManager是框架中這個模式的典型應用。
演算法封裝型整體巨集觀圖如下:
效能與物件訪問型
享元模式
運用共享技術,有效的控制大量細粒度的物件。
使用場景:
應用程式中使用大量物件時。
通過共享減少了多少物件總數。
使用例項:
螢幕上要展示1000朵小花,利用共享可以只用10個imageData物件,1000個座標物件。
代理模式
為其他客戶端提供一種代理,來控制對真實物件的訪問。
遠端代理:用本地物件代替遠端物件。如:傳送網路時的代理伺服器。
虛擬代理:將代理直接面向客戶端,使客戶端認為操作的虛擬代理就是真實物件。虛擬代理提供佔位物件和重型物件。預設使用佔位物件,當需要使用重型物件時才載入。
使用例項:
Object-C不支援多繼承,如果代理物件不是NSObject的子類的話,可以考慮用NSProxy來作為佔位或者替代物件。
儘管NSProxy也是NSObject型別,但是NSProxy的作用就是當代理。
效能與物件訪問型整體巨集觀圖如下:
物件狀態型
備忘錄模式
在不破壞原有封裝的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存狀態。 這樣,之後可將物件恢復到之前的狀態。將狀態封裝成物件儲存。
使用場景:
需要儲存物件在某一時刻的狀態(或部分狀態),這樣以後就可以恢復到先前的狀態。
使用例項:
Cocoa Touch框架在歸檔,屬性列表序列化,核心資料中採用了備忘錄模式。
物件狀態型整體巨集觀圖如下:
完整專案地址如下:
https://github.com/zhfei/Objective-C_Design_Patterns