第九條:以“類族模式”隱藏實(shí)現(xiàn)細(xì)節(jié)
“類族”(class cluster)是一種很有用的模式(pattern),可以隱藏“抽象基類”(abstract base class)背后的實(shí)現(xiàn)細(xì)節(jié)挺勿。
Objective-C的系統(tǒng)框架中普遍使用此模式默辨。
創(chuàng)建類族
首先定義抽象基類
每個(gè)“實(shí)體子類”(concrete subclass)都從基類繼承而來(lái)王暗。
Objective-C語(yǔ)言沒辦法指明某個(gè)基類是“抽象的”(abstract)健提。開發(fā)者通常會(huì)在文檔中寫明類的用法疏橄。這種情況下蝶怔,基類接口一般都沒有名為“init”的成員方法奶浦。
這暗示該類的實(shí)例也許不應(yīng)該由用戶直接創(chuàng)建。
Cocoa里的類族
大部分collection類都是類族踢星。
例如:
在使用NSArray的alloc方法來(lái)獲取實(shí)例時(shí)澳叉,該方法首先會(huì)分配一個(gè)屬于某類的實(shí)例,此實(shí)例充當(dāng)“占位數(shù)組”(placeholder array)沐悦。該數(shù)組稍后會(huì)轉(zhuǎn)為另一個(gè)類的實(shí)例成洗,而那個(gè)類則是NSArray的實(shí)體子類。
像NSArray這樣的類的背后其實(shí)是一個(gè)類族(對(duì)于大部分collection類而言都是這樣)
下面是一個(gè)錯(cuò)誤示例:
id maybeAnArray = /*?…*/;
if([maybeAnArray class] == [NSArray class]){
// will never be hit
}
知道了NSArray是一個(gè)類族藏否,就知道if語(yǔ)句永遠(yuǎn)不會(huì)為真
因?yàn)閇maybeAnArray class]所返回的類絕不可能是NSArray類本身瓶殃,因?yàn)橛蒒SArray的初始化方法所返回的那個(gè)實(shí)例其類型在類族公共接口(public facade)后面的某個(gè)內(nèi)部類型(internal type)。
不過(guò)仍有辦法可以判斷出某個(gè)實(shí)例所屬的類是否位于類族中副签。
使用類查詢方法(introspection method)
id maybeAnArray = /*…*/;
if([maybeAnArray isKindOfClass:[NSArray class]){
//will be hit
}
向類族中增加新子類遥椿,遵守規(guī)則:
1.子類應(yīng)該繼承自類族中的抽象基類
2.子類應(yīng)該定義自己的數(shù)據(jù)存儲(chǔ)方式(抽象基類只是包在其他隱藏對(duì)象外面的殼基矮,它僅僅定義了所有子類都需具備的一些接口)
3.子類應(yīng)當(dāng)覆寫超類文檔中指明需要覆寫的方法
【要點(diǎn)】
1.類族模式可以把實(shí)現(xiàn)細(xì)節(jié)隱藏在一套簡(jiǎn)單的公共接口后面
2.系統(tǒng)框架中經(jīng)常使用類族
3.從類族的公共抽象基類中繼承子類時(shí)要當(dāng)心,若有開發(fā)文檔修壕,則應(yīng)先閱讀