“重載”會(huì)逼瘋一個(gè)程序員嗎?會(huì)!當(dāng)重載在代碼中無(wú)處不在時(shí),真的會(huì)讓一個(gè)接手他人代碼的程序員分分鐘陷入崩潰!重載出現(xiàn)的本意是當(dāng)一個(gè)函數(shù)的默認(rèn)實(shí)現(xiàn)滿足不了現(xiàn)實(shí)需求的時(shí)候,使用重?載則可以直接打破函數(shù)原有邏輯或者在原有邏輯上追加邏輯,大大方便了程序的擴(kuò)展性,但是,我們公司有一個(gè)“大牛”他的重載用法,我看了真的很難受!
![]()
先說(shuō)下重載的用法,首先你得繼承一個(gè)基類,這個(gè)基類中需要定義一個(gè)“虛方法”,大多數(shù)編程語(yǔ)言中,虛方法需要使用virtual關(guān)鍵字來(lái)裝飾,然后繼承這個(gè)基類的實(shí)體類需要重載這個(gè)虛方法,一般使用protected override關(guān)鍵字來(lái)聲明重載。
當(dāng)然,虛方法中你可以定義一些基礎(chǔ)實(shí)現(xiàn),也可以完全不用實(shí)現(xiàn)任何邏輯,但是,不實(shí)現(xiàn)任何邏輯的話,完全只為了讓外部重載這種用法不建議,因?yàn)檫@樣的話,你完全可以不用定義基類和虛方法,聲明一個(gè)接口就完全符合你的要求了!
我們公司的“大牛”使用虛方法的原因就是他想在某些操作中統(tǒng)一去執(zhí)行一些東西,比如說(shuō)一些確定和取消按鈕,當(dāng)點(diǎn)擊時(shí)需要關(guān)閉窗口或者頁(yè)面,所以,但凡是按鈕的確認(rèn)和取消功能他都繼承了含有虛方法的基類,然后直接調(diào)用重載方法去執(zhí)行頁(yè)面的關(guān)閉邏輯!
乍一看好像沒(méi)什么毛病,基類的結(jié)構(gòu)也很簡(jiǎn)單,里面有兩個(gè)虛方法,一個(gè)確認(rèn)方法,一個(gè)取消方法,每個(gè)需方法里面只加了一行代碼,用來(lái)執(zhí)行關(guān)閉窗口或者頁(yè)面的委托(或者說(shuō)邏輯)。
如果你直接調(diào)用虛方法的重載實(shí)現(xiàn)我都沒(méi)什么話說(shuō),主要是在虛方法的基類基礎(chǔ)上又加了兩個(gè)轉(zhuǎn)發(fā)函數(shù),外部在調(diào)用虛方法時(shí)不直接調(diào)用,而是先調(diào)用兩個(gè)轉(zhuǎn)發(fā)函數(shù),由轉(zhuǎn)發(fā)函數(shù)去執(zhí)行基類虛方法的實(shí)現(xiàn)!
![]()
他這么做的原因是因?yàn)榇a框架中確定和取消按鈕必須先實(shí)現(xiàn)代碼框架定義的系統(tǒng)基類中的兩個(gè)虛方法,分別是確定和取消。
這么一來(lái),其實(shí)他自己定義的基類和系統(tǒng)基類中的虛方法其實(shí)就沖突了,而為了硬調(diào)用他自己寫的基類,因此就有了上面所說(shuō)的轉(zhuǎn)發(fā)函數(shù)。
這兩個(gè)轉(zhuǎn)發(fā)函數(shù)是做什么用的呢?其實(shí)道理也很簡(jiǎn)單,因?yàn)榇a框架要求確定和取消必須先實(shí)現(xiàn)系統(tǒng)函數(shù),因此,他在自己寫的基類中線定義了一個(gè)系統(tǒng)函數(shù)的實(shí)現(xiàn),這樣確定和取消按鈕就可以直接調(diào)用這個(gè)實(shí)現(xiàn)。
但是,光調(diào)用實(shí)現(xiàn)不行,自己定義的虛方法也需要實(shí)現(xiàn),因此,在這個(gè)實(shí)現(xiàn)的基礎(chǔ)上,又調(diào)用了對(duì)應(yīng)的虛方法,在前端層面,也就是直接調(diào)用了虛方法的重載!
![]()
是不是很繞?我在看這段代碼的時(shí)候,其實(shí)我也被繞了,雖然道理很簡(jiǎn)單,但是這種“硬控”代碼,我欣賞不來(lái)!
最主要的是,當(dāng)我想要定位按鈕的實(shí)現(xiàn)時(shí),我只能定位到系統(tǒng)函數(shù)的實(shí)現(xiàn),但是,因?yàn)橄到y(tǒng)函數(shù)的實(shí)現(xiàn)是被他寫在虛方法的基類中的,因此,我在定位函數(shù)實(shí)現(xiàn)的時(shí)候首先會(huì)被定位到他自己實(shí)現(xiàn)的函數(shù)基類中。
如果此時(shí)你是第一次看他的代碼,你會(huì)完全摸不著頭腦,因?yàn)槟愕浆F(xiàn)在還沒(méi)發(fā)現(xiàn)函數(shù)的真正實(shí)現(xiàn)直到我去仔細(xì)觀賞他在基類里面寫的代碼,我才知道:哦,原來(lái)他是通過(guò)調(diào)用這個(gè)函數(shù),然后去調(diào)用那個(gè)虛方法的實(shí)現(xiàn)的,所以,我應(yīng)該去前端找這個(gè)名字的虛方法的對(duì)應(yīng)的方法實(shí)現(xiàn)!
![]()
能明白我的糾結(jié)點(diǎn)嗎?比如說(shuō)我要干一件事情,A明明知道我需要干什么事情,當(dāng)我去問(wèn)A時(shí),A說(shuō)他按照流程,得先讓我去B那過(guò)一下,由B把任務(wù)發(fā)布給我,然后我到了B那以后,B告訴我,我的任務(wù)就是去A那執(zhí)行!
能明白嗎?B的作用只是中轉(zhuǎn)!且如果不經(jīng)過(guò)B,A是不會(huì)告訴我具體應(yīng)該執(zhí)行什么東西的!
如果代碼中到處都充斥著這種代碼,那我在閱讀代碼時(shí)就需要來(lái)來(lái)回回折騰:先定位方法-定位到基類-在基類里面找方法的虛方法-回到原方法去找虛方法的實(shí)現(xiàn)!
除非你對(duì)這套代碼很熟,否則一定會(huì)被代碼給繞進(jìn)去。
我想了很久,他這么干的意圖是什么,最后,我沒(méi)有看到任何好處,只有一點(diǎn),那就是的確代碼變得優(yōu)雅了。
首先,我們公司做的都是非標(biāo)自動(dòng)化項(xiàng)目,排除一些常用的硬件、通訊協(xié)議、UI我們會(huì)封裝成庫(kù)外,其他的基本上每個(gè)項(xiàng)目的代碼邏輯都不一樣,而且,后續(xù)再動(dòng)代碼的可能性極小,即使是客戶想要新增功能,也不會(huì)出現(xiàn)大改的情況。
反而是一個(gè)項(xiàng)目代碼部署出去可能等第二次客戶要求增加功能時(shí),因?yàn)槲覀冞@個(gè)行業(yè)程序員流動(dòng)性比較大,因此,到那個(gè)時(shí)候當(dāng)初寫這套代碼的人可能都不在了!
因此,代碼的可讀性是最重要的,代碼的可讀性上來(lái)了,應(yīng)對(duì)突發(fā)狀況的反應(yīng)時(shí)間也就會(huì)很快,也會(huì)減少客戶那邊停機(jī)的損失。
結(jié)語(yǔ)
所以,別扯什么設(shè)計(jì)模式,有些時(shí)候,代碼優(yōu)雅的能開(kāi)香檳,也不及讓一個(gè)剛畢業(yè)的程序員能看懂來(lái)得實(shí)際!而一般維護(hù)這些已經(jīng)交付的項(xiàng)目的人,恰恰就是那些經(jīng)驗(yàn)稍淺一些的程序員!
所以,我最后嘆了一口氣,因?yàn)槲腋淖儾涣耸裁矗a本身是來(lái)解決問(wèn)題的,但是有些時(shí)候代碼寫得太通俗易懂反而會(huì)被人說(shuō)成“幼稚”、“不夠優(yōu)雅”。
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.