客戶端某些情況下,在頁(yè)面上進(jìn)行彈窗焚志,比如升級(jí)提示衣迷,促銷彈窗,以及新手引導(dǎo)等酱酬,本文將這些彈窗視為同一種類型壶谒,定義為PopView。
在展示彈窗時(shí)膳沽,會(huì)有很多限制汗菜,比如某個(gè)版本只彈一次,只在第一次登錄后彈挑社,多個(gè)彈窗互斥等陨界。假設(shè)有需求:頁(yè)面上有3種彈窗,view1痛阻,view2菌瘪,view3,展示優(yōu)先級(jí)依次降低阱当。難免會(huì)有類似下面這樣的代碼:
// 假設(shè)優(yōu)先顯示view1
func showPopView() {
if view1.shouldShow:
view1.show()
else if view2.shouldShow:
view2.show()
else if view3.shouldShow:
view3.show()
}
...
func view1CloseCallBack() {
showPopView()
}
func view2CloseCallBack() {
showPopView()
}
這樣的代碼看起來(lái)很丑陋俏扩,而且如果showPopView與view的closeCallBack不在一起,別人來(lái)看代碼的話弊添,只看到了showPopView录淡,會(huì)理解成優(yōu)先展示一次彈窗。
一個(gè)簡(jiǎn)單的彈窗邏輯油坝,出現(xiàn)這種問(wèn)題的本質(zhì)是什么呢嫉戚?
是因?yàn)関iew1,view2免钻,view3毫無(wú)關(guān)系彼水,卻在顯示邏輯上強(qiáng)行加入了互斥與優(yōu)先級(jí)。這種沒(méi)有關(guān)聯(lián)的對(duì)象极舔,引入一個(gè)第三方對(duì)象來(lái)管理凤覆,可以解決這種問(wèn)題。
再次體現(xiàn)了軟件工程里拆魏,不變的真理盯桦,沒(méi)有什么是引入一個(gè)間接對(duì)象解決不了的慈俯。
為此,新建一個(gè)PopviewManager拥峦,提供一個(gè)autoShow(view)的接口贴膘。
func showPopView() {
view1.priority = 1000
view2.priority = 100
view3.priority = 10
popviewManager.autoShow(view1)
popviewManager.autoShow(view2)
popviewManager.autoShow(view3)
}
這樣邏輯就很清晰了,只在showPopView方法里完成了所有的彈窗展示邏輯略号。PopviewManager會(huì)根據(jù)待顯示的views的優(yōu)先級(jí)來(lái)安排展示刑峡,并且在一個(gè)彈窗關(guān)閉后展示優(yōu)先級(jí)較低的彈窗。再也不用回調(diào)玄柠,再也不用if/else突梦,完美!
后來(lái)想了想羽利,這其實(shí)是一個(gè)中介者設(shè)計(jì)模式的的案例宫患,通過(guò)一個(gè)對(duì)象來(lái)封裝一組對(duì)象之間的交互邏輯。也驗(yàn)證了設(shè)計(jì)模式是不斷的優(yōu)秀實(shí)踐的總結(jié)这弧,并沒(méi)有那么玄乎娃闲。也許平時(shí)你習(xí)以為常的一個(gè)設(shè)計(jì),正是某種大名鼎鼎的設(shè)計(jì)模式匾浪。
實(shí)現(xiàn)細(xì)節(jié)上皇帮,因?yàn)镻opView統(tǒng)一都在PopviewManager里控制展示,需要他們擁有統(tǒng)一的判斷接口與展示接口户矢,這里可以用協(xié)議來(lái)實(shí)現(xiàn)玲献。PopviewManager還需要知道PopView的關(guān)閉事件,好啟動(dòng)下一個(gè)展示梯浪。