iOS 設計模式知多少

發表於2016-08-04

什麼是設計模式
設計模式是為特定場景下的問題定製的解決方案,設計模式分三種型別:建立型,結構型,行為型.這裡只列舉iOS常用到的幾種:

建立型 : 單例 , 工廠
結構型 : 代理 , MVC
行為型 : 觀察者 , 策略

單例模式
單例類 : 確保某一個類只有一個例項,而且自行例項化並向整個系統提供這個例項

優點:
1-節省記憶體
每次獲取例項時會先進行判斷,例項存在則返回,否則建立例項,如果一直不用,則不會建立例項,從而節省了內記憶體空間

2-因為單例類控制例項化過程,所以可以更靈活的修改例項化過程

缺點:
1-執行費時間
上面的判斷會浪費一些時間

2-執行緒安全問題
併發情況下,如果執行緒A和執行緒B同時呼叫某一方法,會建立出兩個例項,此時單例模式失效,若想解決執行緒安全問題,需要加synchronized解決,但會降低訪問速度

使用場景:
1-如果建立某一個物件會耗費很多系統資源,此時採取單例模式,因為只需要一個例項,會節省alloc時間

2-若很多模組需要使用同一變數,可以將它放入單例類

3-實際應用:”我的音樂”專案中 “音樂播放器/列表管理/檔案管理”均為單例模式

代理模式

當一個類的某些功能(協議)需要由別的類來實現,但是又不確定具體會是哪個類實現,本質是某個類持有了另一個類的指標
協議是約束一個類必須實現某些方法
協議中只能定義方法,不能定義成員變數,屬性,@required為必須實現的,@optional為可選擇實現的
因為協議這個介面和類並不存在關聯關係,所以我們要用到代理,宣告一個代理屬性,約定實現代理的物件去實現協議方法
說起來有點繞,但理解了就好了….

優點:
1-有利於程式碼的封裝
2-有利於程式的結構化和層次化
3-若是@required的方法,沒有實現會編譯警告/報錯
4-一個類可以定義不同的協議,當然,每個協議得對應不同的delegate

缺點:
1-程式碼量多,協議定義,delegate屬性,本身決定什麼時候執行代理,實現代理類的實現

2-釋放後,delegate要為nil,否則會是野指標,造成記憶體洩漏,這也是要用weak來宣告delegate的原因

3-只能一對一通訊,不過這個好像不算是缺點
備註:
-假如現在有類A,類B,類C
-類C協議為CDelegate,點選類C的按鈕時,相應協議,輸出一句話
-類A和類B都實現了方法
-執行的操作是,從類A跳轉到類B,從類B跳轉至類C,點選類C的按鈕,只有類B相應了

使用場景:
tableView的Cell內按鈕點選時
音樂播放器當前歌曲的進度
……

實現過程:
舉例:類A實現了類B的協議
類B
1.宣告協議及協議方法,這是要讓別的類,比如“A”實現的

2.宣告此協議的代理物件,誰使用了這個代理物件,誰就實現上面的協議,比如“A”

3.本類決定了,實現我代理物件的類,比如“A”,何時實現我的協議方法,例當我點選我本身的按鈕時實現

類A
1.宣告”B”物件,並實現”B”協議的代理

2.實現協議方法,何時實現由”B”控制

拿tableView的cell內按鈕點選舉例

111602974-88c561073190a05d
 121602974-85cfadb98294c63d

擴充套件一:執行時機制
假如我們上面不用代理實現,改成如下依然可以實現:

擴充套件二
1-代理用weak,不用assign的原因
assign和weak均是指標賦值(直接賦值),不改變索引計數,但當被銷燬時,
assign:如果使用完畢,不將其置為nil,會產生野指標,操作不當會崩潰
weak:在屬性所指的物件遭到摧毀時,屬性值也會清空(nil out),不會崩潰

假設你用malloc分配了一塊記憶體,並且把它的地址賦值給了指標a,後來你希望指標b也共享這塊記憶體,於是你又把a賦值給(assign)了b。此時a 和b指向同一塊記憶體,請問當a不再需要這塊記憶體,能否直接釋放它?答案是否定的,因為a並不知道b是否還在使用這塊記憶體,如果a釋放了,那麼b在使用這塊記憶體的時候會引起程式crash掉

2- assigin可以用非 OC 物件,而 weak 必須用於 OC 物件

3- 代理用weak,不用strong的原因,是因為防止迴圈引用

觀察者模式

觀察者模式是一種通知變化的模式,分下面兩種

  • Notification
    優點:
    1-程式碼量少,實現簡單
    2-對於一個發出的通知,多個物件能夠做出反應,即一對多
    缺點:
    1-釋放通知物件時,需要在通知中心移除註冊
    2-觀察者需要提前知道通知的名字,如果未定義,會不同步
    3-編譯器不會檢查通知是否能被觀察者處理(相對比delegate)
  • KVO
    優點:
    1-簡單
    2-能夠對非我們建立的物件,即內部物件的狀態改變做出相應
    3-用key path觀察屬性,因此也可以觀察巢狀物件
    4-也可以一對多
    缺點:
    1-觀察的屬性必須使用NSString定義
  • Delegate,NSNotification,KVO
    1-三者均是類和類之間的通訊
    2-NSNotification和KVO一對多,Delegate一對一
    3-NSNotification和KVO不關心接受者的態度,意思就是發出通知後剩下的事就不管了,而delegate會關注結果

NSNotification例子(帶引數)

KVO會單開專題講解

MVC模式
Model-View-Controller的縮寫,是一種架構模式,講的是M和V的程式碼分離,通過資料模型,控制器邏輯,檢視展示將應用程式進行邏輯劃分。

優點:
1-層次清晰,程式碼簡潔
2-方便測試及改動,易於維護
缺點:
1-增加系統結構和實現的複雜性
2-檢視對模型資料低效率訪問

這個就不舉例子了.

工廠模式

簡單工廠模式: 為了向客戶提供方便,將分配和初始化合在一個步驟中,返回被建立的物件.說白了,就是物件的封裝.
優點:客戶端直接使用產品,而不用關心產品的具體實現
缺點:工廠類負責邏輯實現,一旦出現問題,均受影響,而且,每增加一個產品,就要增加一個工廠類
使用場景:多個地方用到某一物件,並且此物件屬性一樣時

簡單工廠模式例子:
每個應用程式都會有自己的主色調,字型顏色及大小等等吧,我們定義每一個Button時,若都寫給它設定顏色,字型,字號等太麻煩,可以封裝起來,這樣宣告一個Button只需要執行一句程式碼就行啦

131602974-14a956f96c3ad768

類工廠模式:大致可以理解為,通過繼承,建立不同的物件
優點:方便替換
缺點:不能算缺點,只是建立的這些類是同一個父類
使用場景:若使用時類會有變動,比如後臺若傳你不同的資料,需要建不同的類,可以考慮用這個

再舉一個例子,假如後臺返回的資料有不同的型別,根據傳來的key值不同返回不同的物件

策略模式
和工廠模式相比,策略模式是對演算法的封裝,使演算法可以互相替換.

之前看過一個例子,假如你出去旅遊,有多種方案選擇,可以騎自行車,汽車,火車,飛機,每個策略都可以得到相同的結果,但使用的是不同的資源

有一篇講策略模式很好的文章,推薦一下
設計模式之策略模式(iOS開發,程式碼用Objective-C展示)

相關文章