關(guān)于iOS軟件架構(gòu)設(shè)計(jì)模式的粗淺思考

前言

2018年底,對于已經(jīng)從事軟件開發(fā)工作了4年多的我劝堪,經(jīng)歷從輾轉(zhuǎn)深圳、流浪貴陽的顛簸幅聘,由于多年的開發(fā)經(jīng)驗(yàn)凡纳,自我審視的時(shí)候發(fā)現(xiàn)自己業(yè)務(wù)能力不錯(cuò)帝蒿、項(xiàng)目經(jīng)驗(yàn)豐富,但對計(jì)算機(jī)底層缺乏較深的認(rèn)識(shí)巷怜,對設(shè)計(jì)模式也沒有深刻的理解葛超。當(dāng)然延塑,這是我接下來一段時(shí)間工作的重點(diǎn)绣张。

為什么說這么多廢話关带,因?yàn)橹拔也]有打算在本文中探討太專業(yè)的東西侥涵,而本文目標(biāo)也是面向像我一樣深處迷茫探索中的小白,主要從宏觀上聊聊工程結(jié)構(gòu)宋雏、從微觀上聊聊類的設(shè)計(jì)。

本文構(gòu)思基礎(chǔ)
之前在公司開發(fā)遇到幾個(gè)問題

1.項(xiàng)目太大磨总,運(yùn)行調(diào)試太慢嗦明,感覺降低了開發(fā)效率
2.項(xiàng)目由于底層庫的原因不能模擬器調(diào)試蚪燕,只能真機(jī)娶牌,進(jìn)一步降低效率
3.工程文件結(jié)構(gòu)復(fù)雜,開發(fā)人員較多诗良,相關(guān)模塊分離不明顯,難以尋找
4.類似滴滴打車這樣的項(xiàng)目鲁驶,需要開發(fā)多個(gè)客戶端,但功能、網(wǎng)絡(luò)接口等基本相同壹罚,如果使用多個(gè)工程導(dǎo)致大量重復(fù)代碼葛作,將來也不容易同步維護(hù)相同邏輯的代碼

探索思路

1.組件化探索猖凛、插件化設(shè)計(jì)思路
2.多target模塊設(shè)計(jì)思路赂蠢,新建target包裝較復(fù)雜的模塊,一方面可以分離業(yè)務(wù)邏輯辨泳,另一方面也可以使得單個(gè)模塊運(yùn)行速度更快、解決不能真機(jī)調(diào)試問題

新問題

1.公共模塊內(nèi)部引用了其它無關(guān)模塊的邏輯菠红,當(dāng)分離出target以后發(fā)現(xiàn)target并不單純第岖,還是需要引入編譯大量無關(guān)邏輯的代碼试溯,為達(dá)到編譯效率最大化
2.如果需要開發(fā)一個(gè)項(xiàng)目多個(gè)客戶端蔑滓,達(dá)不到邏輯清晰可辨,還是會(huì)帶來維護(hù)上的問題

最終

1.花了大量時(shí)間重構(gòu)了公共模塊代碼键袱,分類模塊之間業(yè)務(wù)邏輯
2.基本類似的功能業(yè)務(wù)遷移重構(gòu),達(dá)到解耦復(fù)用目的
3.只做了項(xiàng)目中一小部分的工作摹闽,難以達(dá)到理想中的效果,不過:一直在路上

思考:不忘初心

  • 宏觀上最初的工程架構(gòu)
  • 微觀上具體到每個(gè)類的設(shè)計(jì)
  • 中觀上建立自己的公共代碼倉庫

關(guān)于工程結(jié)構(gòu)

在開發(fā)新項(xiàng)目前付鹿,你首先應(yīng)該有一個(gè)清晰的工程結(jié)構(gòu)澜汤,無論做什么事情之前我們都應(yīng)該有一段長長的思考舵匾,多對自己提一些疑問俊抵,多像自己談?wù)劇盀槭裁矗俊薄?/strong>

iOS開發(fā)工程目錄結(jié)構(gòu)

在我們熟知的設(shè)計(jì)模式中纽匙,以MVC名頭最響,MVVM更像是另辟蹊徑或者說別出機(jī)杼烛缔,或許有人會(huì)說這是標(biāo)新立異馏段、故意顯擺践瓷,關(guān)于孰優(yōu)孰劣再次不做討論院喜,開發(fā)上的各種思路見仁見智,我個(gè)人更推薦MVVM晕翠。

根據(jù)個(gè)人習(xí)慣有所不同砍濒,有些人喜歡整個(gè)項(xiàng)目結(jié)構(gòu)中就是一個(gè)巨型MVC或者M(jìn)VVM,即外層結(jié)構(gòu)+內(nèi)部模塊硫麻,然后再在“Models/”或者“Views/”、“Controllers/”等目錄下分模塊拿愧,如GitHub優(yōu)秀APP源碼Coding-iOS客戶端杠河。

最外層MVC

而有些人喜歡這樣分浇辜,外層模塊+內(nèi)部結(jié)構(gòu)券敌,如下圖方式

模塊內(nèi)MVC

具體宏觀上用什么目錄結(jié)構(gòu)見仁見智柳洋,記住沒有最好只有更好待诅,對我來說我推薦第一種,可能是習(xí)慣亦或是對大神的仰慕熊镣。

不管什么方式,只要在自己心目中設(shè)計(jì)的時(shí)候按照清晰的MVC或者M(jìn)VVM設(shè)計(jì)轧钓,就非常容易理清邏輯序厉,但對于一個(gè)工程來說毕箍,微觀上的架構(gòu)可能才是最重要的,因?yàn)槲覀冊诨◣滋鞎r(shí)間建立好工程后道盏,接下來的所有日志都主要集中在微觀邏輯架構(gòu)的開發(fā)維護(hù)上而柑,因此我說微觀上的架構(gòu)更重要荷逞,而最初的架構(gòu)設(shè)計(jì)確實(shí)無與倫比的媒咳,將決定了項(xiàng)目未來的代碼如何發(fā)展、是否易于擴(kuò)展涩澡、開發(fā)和維護(hù)等。

關(guān)于類的設(shè)計(jì)

我們常說到低耦合坠敷、高內(nèi)聚思想妙同,基本任何開發(fā)人員都知道這個(gè)概念膝迎,但在設(shè)計(jì)上卻鮮有人能熟練駕馭粥帚。我們總在不知不覺中被方便的思想左右,不愿意去寫接口協(xié)議芒涡、不愿意去做回調(diào)hook處理,這都是通病,以下通過實(shí)例談?wù)効捶?/strong>

1.設(shè)計(jì)一個(gè)通用類:圖片展示器 ImageBrowser

// ImageBrowser應(yīng)該向外提供如下接口

- images/imageURLs接收方法
- show方法(打開)
- close方法(關(guān)閉)
- block/delegate回調(diào)

// 注意事項(xiàng)
// 1.該類不應(yīng)該使用項(xiàng)目中定義的一些Define费尽、Models、Views等
// 2.該類不應(yīng)該引用項(xiàng)目中某些類的頭文件旱幼,不應(yīng)該和項(xiàng)目中某些類的邏輯相關(guān)聯(lián)乎串,只能向外提供訪問接口
// 3.該類的總體思路應(yīng)該是單向的速警,即項(xiàng)目中類可以訪問它叹誉,而它不能直接訪問項(xiàng)目中的類
// 4.設(shè)計(jì)為插件式模塊,引入和抽離只需少量代碼闷旧,大量初始化工作應(yīng)在內(nèi)部完成,向外提供的應(yīng)該是非常簡潔的接口

2.第三方庫橋接文件忙灼,我們在項(xiàng)目中接入第三方庫的時(shí)候一般不會(huì)直接使用匠襟,應(yīng)該是簡歷橋接文件去和第三方庫對接该园,將來如果第三方庫更換也不用變動(dòng)項(xiàng)目代碼酸舍,只需維護(hù)橋接文件即可。如設(shè)計(jì)一個(gè)AFNetworking的管理類

// 應(yīng)該向外提供如下接口
- get:(參數(shù)) block:(回調(diào)結(jié)果)
- post:(參數(shù)) block:(回調(diào)結(jié)果)
- upload:(參數(shù)) progressBlock:(回調(diào)進(jìn)度) block:(回調(diào)結(jié)果)
...

// 注意事項(xiàng)
// 1.該類只與AFNetworking關(guān)聯(lián)啃勉,不應(yīng)該關(guān)聯(lián)項(xiàng)目中的Define、Models双妨、Views等
// 2.遵循單向訪問邏輯原則
// 3.遵循接口簡介原則

3.設(shè)計(jì)UITableViewCell

// 1.向外暴露需要變動(dòng)展示數(shù)據(jù)的property
@property (nonatomic, weak) UILabel *titleLabel;
@property (nonatomic, weak) UIImageView *imageView;
...

// 向外提供hook接口
- block/delegate回調(diào)

// 注意事項(xiàng)
// 1.該類不應(yīng)該引直接引用Model淮阐,不應(yīng)該在內(nèi)部處理交互事件刁品,應(yīng)hook到controller處理
// 2.該類若必須處理大量內(nèi)部邏輯泣特,考慮綁定viewModel或者為其添加分類Category
// 3.該類不應(yīng)該引用其他模塊的頭文件

4.此外設(shè)計(jì)Tools、Category状您、Helper等工具類的時(shí)候也盡量保持相互間的獨(dú)立性

好處

1.不同模塊角色明晰,代碼均衡分布于這些模塊上
2.由第1點(diǎn)帶來的可測試性
3.易用性兜挨,維護(hù)成本低
4....

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市暑劝,隨后出現(xiàn)的幾起案子骆莹,更是在濱河造成了極大的恐慌,老刑警劉巖幕垦,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丢氢,死亡現(xiàn)場離奇詭異,居然都是意外死亡疚察,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門仇奶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來貌嫡,“玉大人该溯,你說我怎么就攤上這事岛抄。” “怎么了夫椭?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長氯庆。 經(jīng)常有香客問我,道長堤撵,這世上最難降的妖魔是什么仁讨? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮洞豁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘屠橄。我一直安慰自己族跛,他們只是感情好锐墙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著长酗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪夺脾。 梳的紋絲不亂的頭發(fā)上之拨,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天咧叭,我揣著相機(jī)與錄音蚀乔,去河邊找鬼。 笑死菲茬,一個(gè)胖子當(dāng)著我的面吹牛派撕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播睬魂,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼终吼,長吁一口氣:“原來是場噩夢啊……” “哼氯哮!你這毒婦竟也來了际跪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤姆打,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后肠虽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體穴肘,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡舔痕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年评抚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了伯复。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片慨代。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖啸如,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情叮雳,我是刑警寧澤想暗,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布帘不,位于F島的核電站说莫,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏寞焙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一捣郊、第九天 我趴在偏房一處隱蔽的房頂上張望辽狈。 院中可真熱鬧,春花似錦呛牲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至元扔,卻和暖如春躯保,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背澎语。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留擅羞,地道東北人尸变。 一個(gè)月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓减俏,卻偏偏與公主長得像召烂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子娃承,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

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