![]()
MiniScript的PixelDisplay.drawImage有10個(gè)參數(shù)。想給圖片加個(gè)青色濾鏡?你得記住第9個(gè)位置是srcHeight,第10個(gè)才是tint——哪怕前面7個(gè)參數(shù)你根本不想動(dòng)。
作者Joe Strout在文檔里吐槽:「So many times I have typed @gfx.saveImage at the Mini Micro prompt just to remind myself of the order of the parameters!」這種靠運(yùn)行時(shí)查文檔才能寫代碼的體驗(yàn),用過(guò)Python早期版本的人應(yīng)該很熟悉。
但MiniScript故意不支持命名參數(shù)。
Strout見過(guò)25個(gè)參數(shù)的函數(shù)噩夢(mèng)。命名參數(shù)會(huì)讓開發(fā)者肆無(wú)忌憚地堆參數(shù),然后寫一堆校驗(yàn)邏輯確保組合合法,再寫一堆文檔教人怎么用。「I have rarely seen any language feature so quickly lead to bad code as named parameters; it may even take the lead from GOTO in this department.」
他的解決方案是Parameter Object模式——把10個(gè)參數(shù)塞進(jìn)一個(gè)字典,用的時(shí)候按需取用。
10個(gè)參數(shù)的函數(shù)長(zhǎng)什么樣
原版drawImage的簽名:image, left=0, bottom=0, width=-1, height=-1, srcLeft=0, srcBottom=0, srcWidth=-1, srcHeight=-1, tint="#FFFFFF"。
調(diào)用 tinted 圖片的代碼:gfx.drawImage img, 500, 200, -1, -1, 0, 0, -1, -1, color.aqua。數(shù)一下,7個(gè)-1和0的占位符,只為把color.aqua送到第10位。
這種"位置記憶游戲"在Mini Micro這類創(chuàng)意編程環(huán)境里尤其痛苦。用戶想畫個(gè)帶顏色的圖,卻被迫學(xué)習(xí)9個(gè)無(wú)關(guān)參數(shù)的默認(rèn)值。
Parameter Object怎么改
Strout的重構(gòu)版本用單個(gè)params字典替代全部位置參數(shù)。核心依賴mapUtil模塊的get方法,提供默認(rèn)值回退:
g = params.get("gfx", gfx)
g.drawImage params.image, params.get("left", 0), params.get("bottom", 0)...
調(diào)用變成:drawImage {"image": img, "tint": color.aqua}。只傳想改的,其余自動(dòng)走默認(rèn)。
這個(gè)模式在MiniScript里有個(gè)額外好處:字典可以存進(jìn)變量,反復(fù)傳遞。
比如一組圖片都用相同的left/bottom/width/tint配置,先打包成options = {"left": 100, "bottom": 200, "tint": color.red},然后循環(huán)里只改image鍵。helper方法之間傳參也清爽很多。
為什么不直接支持命名參數(shù)
Strout的觀點(diǎn)很直接:語(yǔ)言特性會(huì)塑造編碼習(xí)慣。命名參數(shù)降低設(shè)計(jì)成本,導(dǎo)致函數(shù)膨脹,最終傷害的是代碼可維護(hù)性。
Parameter Object是顯式的妥協(xié)。你仍然可以寫爛代碼,但至少要定義一個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)承載參數(shù),這個(gè)步驟本身就在提醒"這里可能需要重新設(shè)計(jì)"。
MiniScript的定位是教育/創(chuàng)意編程語(yǔ)言。它的用戶很多是編程新手,或者從Scratch過(guò)渡來(lái)的青少年。強(qiáng)制簡(jiǎn)潔的函數(shù)簽名,比提供"強(qiáng)大但易濫用"的特性更符合目標(biāo)場(chǎng)景。
Strout在文末留了個(gè)開放實(shí)現(xiàn):「In your own code, you could actually replace the original method with the refactored one」。但Mini Micro的API凍結(jié)了,所以示例代碼選擇包裝而非替換。
這種"舊接口包新接口"的技巧,在維護(hù)遺留系統(tǒng)時(shí)很常見。你沒法改底層,但可以給用戶層提供更好的抽象。
最后他鼓勵(lì)讀者:「I encourage you to fire up Mini Micro, either locally or on the web, and follow along for yourself。」
試過(guò)在瀏覽器里跑Mini Micro的人會(huì)發(fā)現(xiàn),它的REPL環(huán)境確實(shí)適合這種即學(xué)即改的探索。10個(gè)參數(shù)的drawImage和1個(gè)參數(shù)的drawImage,你更愿意維護(hù)哪個(gè)?
特別聲明:以上內(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.