設(shè)計(jì)模式的學(xué)習(xí)筆記

起因是這樣的,還記得夏天的時(shí)候.再一次上班的路上,和前公司前端大牛閑聊說道Facebook開源的一個(gè)庫,里面都是用url作為驅(qū)動(dòng),進(jìn)行VC之間的跳轉(zhuǎn).當(dāng)時(shí)一知半解,就覺得這樣設(shè)計(jì)所有的頁面或者view更像一個(gè)組件,可以通過url被拉起來.視圖之間的輪轉(zhuǎn)會(huì)變得跟加直接.當(dāng)時(shí)想著Facebook的工程師們太高產(chǎn)了.

這事就一直放著了,然后最近無意在微博上看到一個(gè)iOS開發(fā)者寫的博客<iOS應(yīng)用架構(gòu)談 組件化方案>突然想起之前那次閑聊時(shí)候的話題,引發(fā)了興趣,隨即把大神的幾篇文章都讀了一遍,感觸頗深.起先寫項(xiàng)目的時(shí)候從沒考慮過架構(gòu)的問題,就是那么寫也沒想著以后版本遷移,后續(xù)增加模塊,覺得項(xiàng)目理所應(yīng)當(dāng)這么寫.看過博主的文章之后,決定好好學(xué)習(xí)一下設(shè)計(jì)模式.

以大神的一篇關(guān)于跳出面向?qū)ο蟮乃枷?-繼承這篇文章結(jié)合最近看的設(shè)計(jì)模式的書,簡單梳理一下我的學(xué)習(xí)思路:
首先是繼承,用過的人多知道它有多好用,在基類里面做統(tǒng)一設(shè)置,所有的派生類再也不用謝重復(fù)的代碼.光想想就是爽.可是,東西好用就有它的缺陷,它的缺點(diǎn)也暴露的很明顯:高耦合.

大神在他的博客中舉了個(gè)簡單的場景:產(chǎn)品經(jīng)理提出一個(gè)需求,需要在首頁,及其的他子頁面寫個(gè)搜索框.接到需求的程序員決定從之前寫好的搜索框派生出一個(gè)新的:HOME_SEARCH_BAR派生出PAGE_SEARCH_BAR,目前就這么看,完全沒有任何問題,

需求增加,經(jīng)理要求子頁面的搜索需要多一個(gè)本地搜索的功能,于是你會(huì)在PAGE_SEARCH_BAR增加一個(gè)locasearch功能.之后變態(tài)的要求來了.經(jīng)理提出來,把首頁的搜索換一個(gè)樣式,但是子頁面的還保持原來的樣子.這個(gè)需求看似簡單,但是用繼承的你確知道,有多蛋疼.首頁你需要在基類的初始化里面寫case,隨著項(xiàng)目的進(jìn)展,越來越多的子類,swich case大法慢慢寫吧.

然后別的地方需要用你寫的localsearch功能,卻發(fā)現(xiàn)需要把你所寫的基類全部拿出來,如果你基類里面又引用了別的東西,只能呵呵.

大神在他的博客給出的解決方案是:用組合替代繼承。將Textfield和search模塊拆開,然后通過定義好的接口進(jìn)行交互,一般來說可以選擇Delegate模式來交互。

,搜索框和搜索邏輯分別形成了兩個(gè)不同的組件,分別在HOME_SEARCH_BAR,PAGE_SEARCH_BAR,LOCAL_SEARCH_BAR中以不同的形態(tài)組合而成。textField和SEARCH_LOGIC之間通過delegate的模式進(jìn)行數(shù)據(jù)交互。 這樣就解決了上面提到的兩種類型的問題。

剛好我在iOS設(shè)計(jì)模式里面也看到類似的做法,它取名叫橋接模式.

舉個(gè)列子:要模擬實(shí)現(xiàn)兩個(gè)游戲機(jī)的操作,游戲機(jī)分別用AB代替.

首先游戲機(jī)A和B都有左手邊都有上下左右四個(gè)鍵位,右手邊OX兩個(gè)按鍵,中間是開始鍵位,其中A在右邊還有一個(gè)選擇鍵,B沒有.除了鍵位有少許差別,面板操作幾乎完全一樣.如果你開始打算為每個(gè)具體游戲機(jī)設(shè)計(jì)專用的控制器,那么勢必會(huì)有很多冗余.而且可能以后會(huì)導(dǎo)致子類游戲機(jī)的激增.以后的業(yè)務(wù)也許派生出來的子類可能不需要方向鍵,而是從加速到讀取方向的變化,從而模擬上下左右.

所以最好的做法是把虛擬的控制器和游戲機(jī)分離.這樣他們就能獨(dú)立的變化.從而不影響對方的代碼.話句話來說,它們是有各自的類層次.兩個(gè)層次會(huì)有不同的接口,通過對象組合的方法連接起來.它們之間的靜態(tài)結(jié)構(gòu)圖是這樣的:

consoleVC(setCommand)----------->consoleEmulator(接受command)

| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ??

| ? ? ? ? ? A游戲機(jī)(接受command, 執(zhí)行方法) ? ? ? ? ?B游戲機(jī)(接受command,執(zhí)行方法)

| ? ? ? ? ? ? ? ? ? ? ? ? ?

touchVC( [super setCommand] ? 上下左右選擇開始OX)


consoleVC和consoleEmulator分別是虛擬控制器和游戲機(jī)的抽象類,這兩個(gè)類有不同的接口,在consoleVC中封裝一個(gè)隊(duì)Emulator的引用.consoleVC的實(shí)例可以在抽象層上是用Emulator的實(shí)例.這就完成了兩個(gè)類的橋接.

Emulator為其子類定制個(gè)性化接口,用于處理游戲機(jī)的底層指令.

consoleVC有個(gè)相對底層的方法,向橋接端再發(fā)送基本命令,它的set方法接受預(yù)先設(shè)定好的command,并通過"接受command"把消息轉(zhuǎn)發(fā)給內(nèi)嵌的Emulator.


指令集



模擬器基類


游戲機(jī)A,游戲機(jī)B和a類似,就不寫了.


控制器.h


控制器.m




我們想讓所有的方法使用父類中的同一個(gè)setCommand實(shí)現(xiàn),通過super 而不是self發(fā)送消息.通過橋接模式,可以看到組合對象的力量.我們?yōu)閏onsoleEmulator實(shí)現(xiàn)的橋接不可能通過直接的繼承來實(shí)現(xiàn).

這也是大神所提倡的優(yōu)先使用對象組合的形式而不是繼承.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 設(shè)計(jì)模式基本原則 開放-封閉原則(OCP),是說軟件實(shí)體(類、模塊、函數(shù)等等)應(yīng)該可以拓展,但是不可修改。開-閉原...
    西山薄涼閱讀 4,086評論 3 14
  • 震驚!小豬的設(shè)計(jì)模式初涉總結(jié)!純干貨~ 標(biāo)簽: 知識(shí)點(diǎn)總結(jié) 描述性文字 今年一月初有了離職的念頭后,就盤算著把設(shè)計(jì)...
    coder_pig閱讀 1,189評論 0 24
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,654評論 4 61
  • 那顆糖好甜 十幾年的光陰也不散 許你高樓廣廈 可是 可是 你說話不算數(shù) 只留我一人信守承諾 看到路邊散步的老太太 ...
    小白army閱讀 338評論 0 3
  • 原文鏈接:http://blog.csdn.net/qq_22329521/article/details/601...
    越長越圓閱讀 3,263評論 0 0

友情鏈接更多精彩內(nèi)容