第四章 協(xié)議與分類—第24條:將類的實(shí)現(xiàn)代碼分散到便于管理的數(shù)個(gè)分類之中

類中經(jīng)常容易填滿各種方法,而這些方法的代碼則全部堆在一個(gè)巨大的實(shí)現(xiàn)文件里。有時(shí)這么做是合理的房轿,因?yàn)榧幢阃ㄟ^重構(gòu)把這個(gè)類打散,效果也不會(huì)更好所森。在此情況下囱持,可以通過Objective-C的"分類"機(jī)制,把類代碼按邏輯劃入幾個(gè)分區(qū)中必峰,這對(duì)開發(fā)與調(diào)試都有好處洪唐。
比如說,我們把個(gè)人信息建模為類吼蚁。那么這個(gè)類就可能包含下面幾個(gè)方法:

#import <Foundation/Foundation.h>

@interface EOCPerson : NSObject
@property (nonatomic, copy, readonly) NSString *firstName;
@property (nonatomic, copy, readonly) NSString *lastName;
@property (nonatomic, strong, readonly) NSArray *friends;

- (id)initWithFirstName:(NSString*)firstName andLastName:(NSString*)lastName;

/* Friendship methods */
- (void)addFriend:(EOCPerson*)person;
- (void)removeFriend:(EOCPerson*)person;
- (BOOL)isFriendsWith:(EOCPerson*)person;

/* Work methods */
- (void)performDaysWork;
- (void)takeVacationFromWork;

/* Play methods */
- (void)goToTheCinema;
- (void)goToSportsGame;

@end

在實(shí)現(xiàn)該類時(shí)凭需,所有方法的代碼可能會(huì)寫在一個(gè)大文件里。如果還向類中繼續(xù)添加方法的話肝匆,那么源代碼文件就會(huì)越來越大粒蜈,變得難于管理。所以說旗国,應(yīng)該把這樣的類分成幾個(gè)不同的部分枯怖。例如,可以用"分類"機(jī)制把剛才的類改寫成下面這樣:

#import <Foundation/Foundation.h>

@interface EOCPerson : NSObject
@property (nonatomic, copy, readonly) NSString *firstName;
@property (nonatomic, copy, readonly) NSString *lastName;
@property (nonatomic, strong, readonly) NSArray *friends;

- (id)initWithFirstName:(NSString*)firstName 
            andLastName:(NSString*)lastName;
@end

@interface EOCPerson (Friendship)
- (void)addFriend:(EOCPerson*)person;
- (void)removeFriend:(EOCPerson*)person;
- (BOOL)isFriendsWith:(EOCPerson*)person;
@end

@interface EOCPerson (Work)
- (void)performDaysWork;
- (void)takeVacationFromWork;
@end

@interface EOCPerson (Play)
- (void)goToTheCinema;
- (void)goToSportsGame;
@end

現(xiàn)在能曾,類的實(shí)現(xiàn)代碼按照方法分成了好幾個(gè)部分度硝。所以說,這項(xiàng)語(yǔ)言特性當(dāng)然就叫做"分類"啦寿冕。在本例中蕊程,類的基本要素(諸如屬性與初始化方法等)都聲明在"主實(shí)現(xiàn)"(main implementation)里。執(zhí)行不同類型的操作所用的另外幾套方法則歸入各個(gè)分類中驼唱。
使用分類機(jī)制之后藻茂,依然可以把整個(gè)類都定義在一個(gè)接口文件中,并將其代碼寫在一個(gè)實(shí)現(xiàn)文件里”娲停可是优俘,隨著分類數(shù)量增加,當(dāng)前這份實(shí)現(xiàn)文件很快就膨脹得無法管理了掀序。此時(shí)可以把每個(gè)分類提取到各自的文件中去帆焕。以EOCPerson為例,可以按照其分類拆分成下列幾個(gè)文件:

  • EOCPerson + Friendship(.h/.m)
  • EOCPerson + Work(.h/.m)
  • EOCPerson + Play(.h/.m)
    比方說森枪,與交友功能相關(guān)的那個(gè)分類可以這樣寫:
// EOCPerson+Friendship.h
#import "EOCPerson.h"

@interface EOCPerson (Friendship)
- (void)addFriend:(EOCPerson*)person;
- (void)removeFriend:(EOCPerson*)person;
- (BOOL)isFriendsWith:(EOCPerson*)person;
@end

// EOCPerson+Friendship.m
#import "EOCPerson+Friendship.h"

@implementation EOCPerson (Friendship)
- (void)addFriend:(EOCPerson*)person {
    …
}
- (void)removeFriend:(EOCPerson*)person {
    …
}
- (BOOL)isFriendsWith:(EOCPerson*)person {
    …
}
@end

通過分類機(jī)制视搏,可以把類代碼分成很多個(gè)易于管理的小塊,以便單獨(dú)檢視县袱。使用分類機(jī)制之后浑娜,如果想用分類中的方法,那么要記得在引入EOCPerson.h時(shí)一并引入分類的頭文件式散。雖然稍微有點(diǎn)麻煩筋遭,不過分類仍然是一種管理代碼的好辦法。
即使類本身不是太大暴拄,我們也可以使用分類機(jī)制將其切割成幾塊漓滔,把相應(yīng)代碼歸入不同的"功能區(qū)"(functional area)中。Cocoa中的NSURLRequest類及其可變版本NSMutableURLRequest類就是這么做的乖篷。這個(gè)類用于執(zhí)行從URL中獲取數(shù)據(jù)的請(qǐng)求响驴,而且通常使用HTTP協(xié)議從因特網(wǎng)中的某個(gè)服務(wù)器上獲取,不過撕蔼,由于該類設(shè)計(jì)得較為通用豁鲤,所以也可以使用其他協(xié)議。與標(biāo)準(zhǔn)的URL請(qǐng)求相比鲸沮,執(zhí)行HTTP請(qǐng)求時(shí)還需要另外一些信息琳骡,例如"HTTP"方法(HTTP method,GET讼溺、POST等)或HTTP頭(HTTP header)楣号。
然而卻不便從NSURLRequest中繼承子類以實(shí)現(xiàn)HTTP協(xié)議的特殊需求,因?yàn)楸绢惏艘惶撞僮鰿FURLRequest數(shù)據(jù)結(jié)構(gòu)所需的C函數(shù)怒坯,所有"HTTP方法"都包含在這個(gè)結(jié)構(gòu)里炫狱。于是,為了擴(kuò)展NSURLRequest類剔猿,把與HTTP有關(guān)的方法歸入名為NSHTTPURLRequest的分類中毕荐,而把與可變版本有關(guān)的方法歸入名為NSMutableHTTPURLRequest的分類中。這樣艳馒,所有底層CFURLRequest函數(shù)就都封裝在同一個(gè)Objective-C類里了,而在這個(gè)類里,與HTTP有關(guān)的方法卻又要單獨(dú)放在一處弄慰,因?yàn)槿羰遣贿@么做的話第美,該類的使用者就會(huì)有疑問,為什么能在使用FTP協(xié)議的request對(duì)象上設(shè)置"HTTP方法"呢陆爽?
之所以要將類代碼打散到分類中還有個(gè)原因什往,就是便于調(diào)試:對(duì)于某個(gè)分類中的所有方法來說,分類名稱都會(huì)出現(xiàn)在其符號(hào)中慌闭。例如别威,"addFriend:"方法的"符號(hào)名"(symbol name)如下:

- [EOCPerson(Friendship) addFriend:]

在調(diào)試器的回溯信息中,會(huì)看到類似下面這樣的內(nèi)容:

frame #2: 0x00001c50 Test '-[EOCPerson(Friendship) addFriend:] + 32 at main.m : 46

根據(jù)回溯信息中的分類名稱驴剔,很容易就能精確定位到類中的方法所屬的功能區(qū)省古,這對(duì)于某些應(yīng)該視為私有的方法來說更是極為有用∩ナВ可以創(chuàng)建名為Private的分類豺妓,把這種方法全都放在里面。這個(gè)分類里的方法一般只會(huì)在類或框架內(nèi)部使用布讹,而無須對(duì)外公布琳拭。這樣一來,類的使用者有時(shí)可能會(huì)在查看回溯信息時(shí)發(fā)現(xiàn)private一詞描验,從而知道不應(yīng)該直接調(diào)用此方法了白嘁。這可算作一種編寫"自我描述式代碼"(self-documenting code)的辦法。
在編寫準(zhǔn)備分享給其他開發(fā)者使用的程序庫(kù)時(shí)膘流,可以考慮創(chuàng)建Private分類絮缅。經(jīng)常會(huì)遇到這樣一些方法: 它們不是公共API的一部分,然而卻非常適合在程序庫(kù)之內(nèi)使用睡扬。此時(shí)應(yīng)該創(chuàng)建Private分類盟蚣,如果程序庫(kù)中的某個(gè)地方要用到這些方法,那就引入此分類的頭文件卖怜。而分類的頭文件并不隨程序庫(kù)一并公開屎开,于是該庫(kù)的使用者也就不知道庫(kù)里面還有這些私有方法了。

要點(diǎn)

  • 使用分類機(jī)制把類的實(shí)現(xiàn)代碼劃分成易于管理的小塊
  • 將應(yīng)該視為"私有"的方法歸入名叫Private的分類中马靠,以隱藏實(shí)現(xiàn)代碼
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末奄抽,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子甩鳄,更是在濱河造成了極大的恐慌逞度,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妙啃,死亡現(xiàn)場(chǎng)離奇詭異档泽,居然都是意外死亡俊戳,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門馆匿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抑胎,“玉大人,你說我怎么就攤上這事渐北“⑻樱” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵赃蛛,是天一觀的道長(zhǎng)恃锉。 經(jīng)常有香客問我,道長(zhǎng)呕臂,這世上最難降的妖魔是什么蒋院? 我笑而不...
    開封第一講書人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任摇肌,我火速辦了婚禮已亥,結(jié)果婚禮上咪惠,老公的妹妹穿的比我還像新娘。我一直安慰自己疏尿,他們只是感情好瘟芝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著褥琐,像睡著了一般锌俱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上敌呈,一...
    開封第一講書人閱讀 51,482評(píng)論 1 302
  • 那天贸宏,我揣著相機(jī)與錄音,去河邊找鬼磕洪。 笑死吭练,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的析显。 我是一名探鬼主播鲫咽,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼谷异!你這毒婦竟也來了分尸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤歹嘹,失蹤者是張志新(化名)和其女友劉穎箩绍,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尺上,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡材蛛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年圆到,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仰税。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡构资,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出陨簇,到底是詐尸還是另有隱情,我是刑警寧澤迹淌,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布河绽,位于F島的核電站,受9級(jí)特大地震影響唉窃,放射性物質(zhì)發(fā)生泄漏耙饰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一纹份、第九天 我趴在偏房一處隱蔽的房頂上張望苟跪。 院中可真熱鬧,春花似錦蔓涧、人聲如沸件已。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)篷扩。三九已至,卻和暖如春茉盏,著一層夾襖步出監(jiān)牢的瞬間鉴未,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工鸠姨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留铜秆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓讶迁,卻偏偏與公主長(zhǎng)得像连茧,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子添瓷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,126評(píng)論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理梅屉,服務(wù)發(fā)現(xiàn),斷路器鳞贷,智...
    卡卡羅2017閱讀 134,656評(píng)論 18 139
  • 第一搀愧,先慢下來惰聂。不是不做疆偿,而是想清楚了再去做。? 先把心靜下來搓幌,看清楚了才能想清楚杆故,想清楚再去做。 在這個(gè)時(shí)代僅憑...
    玉米南瓜胡蘿卜閱讀 606評(píng)論 0 0
  • 鬢影重疊遠(yuǎn)溉愁,香風(fēng)卷弱襟处铛。 小軒窗一敞偷心。 春色如今方好拐揭,爭(zhēng)用自持矜撤蟆? 此景緣應(yīng)短,何須挽留頻堂污? 又聽聞遠(yuǎn)處拂琴家肯。...
    陳婉_閱讀 274評(píng)論 1 0
  • 【2017年03月01星期三——咖啡冥想】 財(cái)富目標(biāo):我近期最想實(shí)現(xiàn)的一個(gè)愿望或目標(biāo)是:保險(xiǎn)每個(gè)月業(yè)績(jī)?cè)鲩L(zhǎng)2倍,收...
    熱瓦昆空閱讀 217評(píng)論 1 2