這篇文章主要講解了“如何理解編輯器思維與系統(tǒng)設(shè)計(jì)思想”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“如何理解編輯器思維與系統(tǒng)設(shè)計(jì)思想”吧!
按需設(shè)計(jì)網(wǎng)站可以根據(jù)自己的需求進(jìn)行定制,成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)構(gòu)思過(guò)程中功能建設(shè)理應(yīng)排到主要部位公司成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)的運(yùn)用實(shí)際效果公司網(wǎng)站制作網(wǎng)站建立與制做的實(shí)際意義
與人類社會(huì)的歷史相比,計(jì)算機(jī)的歷史非常短暫,上世紀(jì)五、六十年代都能稱為遠(yuǎn)古時(shí)期了。但計(jì)算機(jī)的歷史又很神奇,早期的思想往往都很超前、很先進(jìn)。比如EJB技術(shù)雖然是1998年提出的,但它的設(shè)計(jì)很超前,諸如微服務(wù)等后面出現(xiàn)的技術(shù)都或多或少借鑒了它的思想。通過(guò)了解計(jì)算機(jī)技術(shù)的發(fā)展歷史,往往能從中找到很多有創(chuàng)意的想法,能幫我們解決當(dāng)下的問(wèn)題。所以,今天想來(lái)掰扯一下Emacs和Vim這兩款經(jīng)久不衰的老古董軟件的歷史八卦,看看有沒(méi)有值得借鑒的地方。
Vim族譜
首先從Vim編輯器的起源說(shuō)起,下圖Vim的族譜:
Vim的前身是ed編輯器:
ed是UNIX系統(tǒng)上最古老的程序之一,從第一版本開(kāi)始就入駐了,作者是Ken Thompson(UNIX作者之一)。它提供了面向行(Line)的基本編輯命令。
ex是ed的超集,是Bill Joy(Sun公司創(chuàng)始人之一)在開(kāi)發(fā)BSD時(shí)增強(qiáng)了ed,于是取名叫ex。但ex仍然是面向行的編輯器。
Bill Joy后續(xù)又為ex提供了可視化界面(Viusal Interface),提供全屏編輯能力,因此命名為vi。
為了將vi移植到Amiga機(jī)器,Bram Moolenaar開(kāi)發(fā)了Vi IMitation(Vi仿制品)。隨著功能的不斷增加,名字也升級(jí)為Vi IMproved(Vi改良版),即Vim。
ed編輯器
ed與VSCode、Sublime Text等現(xiàn)代編輯器有很大不同,如前文所說(shuō),它是一款行編輯器(此處已幫大家劃重點(diǎn)),即編輯的對(duì)象是一整行文本。
ed分命令模式與編輯模式。啟動(dòng)ed后,默認(rèn)進(jìn)入命令模式,等待用戶輸入一條條命令。ed通過(guò)執(zhí)行這些命令,最終達(dá)到編輯文件的目的。使用Mac電腦的同學(xué)可以試試在終端里執(zhí)行ed。ed命令的格式是[尋址][命令]:
尋址:選中待操作的目標(biāo)行。ed提供了三種尋址方法:行號(hào):從1開(kāi)始的整數(shù);$代表最后一行。模式:選中與正則表達(dá)式匹配的行。默認(rèn)從當(dāng)前行開(kāi)始,選中第一個(gè)匹配的行。如/re/。添加前綴g,則做全局匹配。如g/re/范圍:由兩個(gè)地址組成的尋址范圍,[地址],[地址]。如/BEGIN/,/END/
命令:用單個(gè)字符表示。以下是最常用的命令:p:展示,輸出目標(biāo)行。i:插入,將內(nèi)容插入到目標(biāo)行的上一行。a:追加,將內(nèi)容追加到目標(biāo)行的下一行。c:更改,替換目標(biāo)行的內(nèi)容。d:刪除,刪除目標(biāo)行。s:替換,用正則表達(dá)式替換匹配行內(nèi)容。
其中i、a、c命令會(huì)使ed從命令模式進(jìn)入編輯模式,在編輯模式中輸入一行.則返回命令模式。以下是ed編輯的幾個(gè)示例:
刪除所有空行:g/^$/d。用前綴g全局搜索正則表達(dá)式/^$/,并執(zhí)行刪除命令。
輸出所有包含“re”的行:g/re/p。同樣全局搜索正則表達(dá)式/re/,并執(zhí)行展示命令。因?yàn)樵摴δ軐?shí)在太常用了,所以還特地開(kāi)發(fā)了一個(gè)命令“grep”。
編輯器思維
如前文所說(shuō),ed編輯器與現(xiàn)代編輯器很不同,它其實(shí)是一個(gè)編輯命令解釋器;但ed編輯器又與現(xiàn)代編輯器很相同,所有編輯器的本質(zhì)都是在不斷執(zhí)行“尋址”與“命令”,不同類型編輯器之間的差異只是編輯的對(duì)象不同:
ed是文本行編輯器:編輯的對(duì)象是文本行。
Microsoft Word是文檔編輯器:編輯的對(duì)象是章節(jié)、段落、詞句等文檔元素。
Sketch是圖形編輯器:編輯的對(duì)象是點(diǎn)、線、面等圖形元素。
IntelliJ IDEA包含Java代碼編輯器:編輯的對(duì)象是類、方法、語(yǔ)句等Java語(yǔ)義元素。
jQuery是DOM編輯器:編輯的對(duì)象是DOM元素。先用CSS Selector尋址,選中要處理的DOM元素;再用連綴表達(dá)式執(zhí)行一系列編輯動(dòng)作。
……
由此可見(jiàn),編輯器思維無(wú)處不在,只要符合“尋址+命令”模式都可稱作編輯器,因此萬(wàn)物皆可編輯!編輯器思維或編輯的本質(zhì),用開(kāi)發(fā)者更熟悉的話術(shù)來(lái)講就是CRUD:
若以后有人質(zhì)疑開(kāi)發(fā)同學(xué)只是在做簡(jiǎn)單的增刪改查,請(qǐng)勇敢地告訴他們:其實(shí)我是在做一個(gè)垂直領(lǐng)域的編輯器!
若意識(shí)到自己在做的其實(shí)是一個(gè)編輯器,就能利用編輯器思維快速發(fā)現(xiàn)系統(tǒng)能力的短板。以商品管理系統(tǒng)為例,若商品管理只提供通過(guò)ID查詢商品的功能,就猶如ed編輯器只支持用行號(hào)來(lái)尋址一樣,使用就非常不方便,可以借鑒ed通過(guò)正則表達(dá)式的模式匹配尋址能力,提供通過(guò)商品名稱等信息來(lái)匹配商品、甚至通過(guò)商品照片來(lái)匹配相似商品的能力;類似的,創(chuàng)建商品能力也可以借鑒編輯器復(fù)制粘貼的能力,提供用相似商品快速新建商品的能力,甚至還可以提供從其他平臺(tái)搬家的能力。
ed的族譜
前文只介紹了ed交互式編輯的功能,其實(shí)ed還支持腳本化編輯,就是將輸入到終端的編輯命令保存成一個(gè)腳本文件,供后續(xù)反復(fù)運(yùn)行。好處是可以用相同的編輯命令批量編輯任意多個(gè)文件。
上圖是ed編輯器的族譜,后續(xù)的衍生程序都是選擇并增量了ed的部分能力。比如:
ex、vi、vim這條分支選擇了交互式路線。
grep、fgrep、egrep選擇了模式匹配路線。
sed、awk選擇了腳本化路線。
從Vim陣營(yíng)叛逃
我曾經(jīng)是一名Vim重度用戶,因?yàn)樵诖髮W(xué)利用的操作系統(tǒng)是Debian Linux,無(wú)論是寫C代碼還是Java代碼,都是在Vim里一把梭。好處是閉卷筆試時(shí)可以直接默寫,而用Eclipse的同學(xué)基本是記不住JDK API的全名。:-p
畢業(yè)后進(jìn)了一家外企,不得不開(kāi)始使用Windows XP系統(tǒng),某天在記事本里寫東西,發(fā)現(xiàn)自己會(huì)經(jīng)常無(wú)意識(shí)地按一下Esc鍵。用過(guò)Vim的同學(xué)肯定知道,這是在切換模式。這我意識(shí)到:Vim這種多模式的設(shè)計(jì)非常反人類。Vim啟動(dòng)時(shí)默認(rèn)進(jìn)入的不是編輯模式,當(dāng)新手用戶什么都還沒(méi)學(xué)會(huì)時(shí),他沒(méi)辦法把Vim當(dāng)成普通的記事本來(lái)用。曾有一則關(guān)于Vim的笑話,說(shuō)如何獲得一串隨機(jī)碼,答案是讓Vim新手嘗試退出Vim。
這種方式不符合我的口味,我嘗試去尋找新的編輯器——當(dāng)什么都沒(méi)學(xué)會(huì)的時(shí)候,可以當(dāng)成最普通的記事本來(lái)用;當(dāng)需要高級(jí)功能時(shí),再通過(guò)快捷鍵等方式呼喚出來(lái)。結(jié)果發(fā)現(xiàn)Emacs恰好符合這個(gè)要求,所以從2010年開(kāi)始我就從Vim陣營(yíng)叛逃到了Emacs陣營(yíng)。我認(rèn)為這個(gè)使用方式的差異是Vim與Emacs最本質(zhì)的區(qū)別:Vim會(huì)強(qiáng)迫用戶從一開(kāi)始就按照它的規(guī)則來(lái)做事情;而Emacs則相對(duì)不需要過(guò)多前置知識(shí)。網(wǎng)絡(luò)上曾流傳過(guò)一張編輯器的學(xué)習(xí)曲線,還蠻貼切的:
Emacs的起源
Vim的前身ed源自UNIX系統(tǒng),而Emacs的前身TECO源自UNIX系統(tǒng)的前身——Multics系統(tǒng)。
上世紀(jì)70年代,GNU的創(chuàng)始人Richard Stallman在MIT的AI實(shí)驗(yàn)室打工時(shí),發(fā)明了TECO編輯器,運(yùn)行在PDP-10機(jī)器上。與ed類似,TECO也是命令解釋器——接收并執(zhí)行編輯命令——并且也采用單個(gè)字符作為命令名稱,比如“l(fā)”是移動(dòng)一行,“5l”是移動(dòng)5行。MIT那群大佬們想用TECO命令完成一些復(fù)雜的編輯工作,于是加入了分支判斷、循環(huán)等功能;但由于先天不足,TECO最開(kāi)始設(shè)計(jì)的時(shí)候,沒(méi)有把命令設(shè)計(jì)成一套完備的編程語(yǔ)言,導(dǎo)致后續(xù)改進(jìn)也很困難,比如命令名稱只能是單個(gè)字符,很快字符就不夠用了。
所謂基礎(chǔ)不牢地動(dòng)山搖,大伙兒都認(rèn)為需要用一套嚴(yán)謹(jǐn)完備的編程語(yǔ)言替代TECO的半成品腳本語(yǔ)言。于是有一位叫Bernie的教授在Multics系統(tǒng)上用MacLisp重寫了TECO,并命名為Emacs,還為它寫了詳細(xì)的手冊(cè),教大家如何擴(kuò)展這個(gè)編輯器來(lái)滿足自己的工作需要。結(jié)果,這個(gè)版本的Emacs取得巨大成功,連Bernie的秘書——一個(gè)號(hào)稱自己不懂編程的人——都在照著手冊(cè),有模有樣地寫Lisp代碼來(lái)擴(kuò)展編輯器功能。這件事兒在實(shí)驗(yàn)室引起轟動(dòng)后,Bernie為此做了一個(gè)總結(jié):如果有一個(gè)應(yīng)用——一個(gè)能幫你做點(diǎn)有用事情的程序——內(nèi)嵌了Lisp,并且能通過(guò)Lisp程序擴(kuò)充它的功能,對(duì)于學(xué)習(xí)編程而言,這是一種非常不錯(cuò)的入門方式!那些自認(rèn)為不會(huì)編程的人,這種方式會(huì)給他們編寫小但有用的程序的機(jī)會(huì),讓他們?cè)趯?shí)踐中不斷成長(zhǎng),直到他們發(fā)現(xiàn)自己就是在編程。
Stallman他們覺(jué)得這個(gè)想法簡(jiǎn)直屌炸天!同時(shí)他們想把這個(gè)好用的Emacs版本遷移到Multics系統(tǒng)之外的其他系統(tǒng),但當(dāng)時(shí)只有Multics系統(tǒng)上有完備的Lisp環(huán)境——既有編譯器又有解釋器——諸如UNIX等系統(tǒng)上都沒(méi)有。
這里還有一個(gè)小插曲,Java之父James Gosling當(dāng)年還寫了一個(gè)能跨平臺(tái)的Emacs版本,叫Gosmacs。本來(lái)社區(qū)想來(lái)一起完善這個(gè)版本,結(jié)果Gosling把它賣給了一家商業(yè)公司,同時(shí)它底層的Lisp不是一個(gè)真實(shí)完備的Lisp,而是一個(gè)叫Mocklisp的假Lisp,只是語(yǔ)法上和Lisp長(zhǎng)得像而已。所以社區(qū)最終放棄了這個(gè)選項(xiàng),決定從頭開(kāi)始做一個(gè)全新的Emacs,也就是GNU Emacs。Stallman先用C語(yǔ)言開(kāi)發(fā)一個(gè)跨平臺(tái)的Lisp解釋器——Emacs Lisp,再用Lisp實(shí)現(xiàn)編輯邏輯。這樣既能在所有平臺(tái)上用統(tǒng)一的Lisp方言來(lái)寫Emacs擴(kuò)展,又能兼顧性能。
GNU Emacs有一段時(shí)間發(fā)展比較之后,因?yàn)镾tallman自己一個(gè)人忙不過(guò)來(lái),所以社區(qū)又創(chuàng)建了一個(gè)分支叫XEmacs,增強(qiáng)了字體抗鋸齒等功能。后來(lái)GNU Emacs的維護(hù)又變得積極了,把很多XEmacs的特性合并回GNU Emacs,所以現(xiàn)在XEmacs差不多是廢棄狀態(tài),主流版本還是GNU Emacs。
編輯器圣戰(zhàn)
程序員的世界里充滿了鄙視鏈,有編輯器鄙視鏈、編程語(yǔ)言鄙視鏈、操作系統(tǒng)鄙視鏈……為什么這些圣戰(zhàn)永遠(yuǎn)打不完,到底是像《格列夫游記》里小人國(guó)因爭(zhēng)論剝雞蛋先打破大頭還是小頭而發(fā)動(dòng)了戰(zhàn)爭(zhēng),還是真的魚(yú)和熊掌不可兼得?
前文提到,Vim喜歡強(qiáng)迫用戶按照它的套路來(lái)做事。Vim從ed繼承了行編輯器的特性,底層模型是基于“行”的,所以會(huì)強(qiáng)行要求所有被編輯的對(duì)象適配成它的底層模型。你用Vim寫Java代碼,你編輯的是文本行;你用Vim寫一篇博客,你編輯的是文本行;你用Vim寫一篇論文,你編輯的還是文本行;無(wú)論你編輯的是類、函數(shù)、段落、目錄還是任何其他內(nèi)容,都要先在腦海中翻譯成對(duì)應(yīng)的dd、yy等面向行的編輯命令。
Emacs則是允許用戶先把Emacs改造成目標(biāo)對(duì)象的個(gè)性化編輯器,能認(rèn)識(shí)目標(biāo)模型,比如段落、章節(jié)、目錄等。用一句時(shí)髦的話講就是Emacs有行業(yè)Know-How。同樣的例子:用Emacs寫Java代碼,你編輯的是類、方法、語(yǔ)句……;你用Emacs寫一篇博客,你編輯的是段落、句子……;你用Emacs寫一篇論文,你編輯的是目錄、章節(jié)、正文、索引……。
兩種設(shè)計(jì)方法
造成上述差異的原因是背后兩種不同的設(shè)計(jì)方法,分別稱作自頂向下(Top Down)與自底向上(Bottom Up):
方法自頂向下自底向上描述將大任務(wù)逐級(jí)拆分到顆粒度合適——足夠小、又能做些實(shí)際的事情——的小任務(wù)完善底層編程語(yǔ)言等——讓底層基建不斷逼近業(yè)務(wù)領(lǐng)域——來(lái)適應(yīng)任務(wù)優(yōu)點(diǎn)難度較低,目標(biāo)明確,迭代快速功能完整,適應(yīng)性強(qiáng)缺點(diǎn)與當(dāng)前需求耦合過(guò)緊,應(yīng)對(duì)變化能力稍弱難度較高,進(jìn)展較慢
用Vim編輯屬于自頂向下方法——將編輯任務(wù)持續(xù)拆分,最終拆解到面向行的編輯命令;就像Java日常開(kāi)發(fā),會(huì)逐級(jí)拆分,最終拆解到JDK的API。用Emacs編輯屬于自底向上方法——先完善底層Emacs Lisp語(yǔ)言,逐步抽象出面向業(yè)務(wù)的領(lǐng)域特定語(yǔ)言,最終用DSL完成編輯任務(wù);例如要編輯Markdown文檔,就會(huì)提供諸如移動(dòng)到下一個(gè)段落、下一個(gè)列表項(xiàng)、表格下一個(gè)單元等面向Markdown領(lǐng)域的特定編輯操作。
這兩種設(shè)計(jì)方法的差異并不意味著只是換個(gè)順序?qū)懘a,而是系統(tǒng)抽象過(guò)程的差異,最終體現(xiàn)在系統(tǒng)擴(kuò)展性的差異上。我個(gè)人把系統(tǒng)的可擴(kuò)展分成4個(gè)等級(jí):
硬編碼:系統(tǒng)運(yùn)行時(shí),數(shù)據(jù)和行為都已寫死,不能變化。
可配置:系統(tǒng)運(yùn)行時(shí),數(shù)據(jù)可動(dòng)態(tài)變化,但行為固定不變。
可控制:系統(tǒng)運(yùn)行時(shí),數(shù)據(jù)可動(dòng)態(tài)變化,并且由多種預(yù)定義的行為可供動(dòng)態(tài)選擇。
可編程:系統(tǒng)運(yùn)行時(shí),數(shù)據(jù)可動(dòng)態(tài)變化,同時(shí)行為可在運(yùn)行過(guò)程中動(dòng)態(tài)新增,即用戶可重新系統(tǒng)行為。
自頂向下的極端是硬編碼,會(huì)過(guò)早地把功能限制在當(dāng)前的需求里,后來(lái)的需求只能盡量逼近初始模型;自底向上的極端是可編程,容易過(guò)渡設(shè)計(jì),為未來(lái)不可能變化的場(chǎng)景提供靈活性,甚至?xí)兂梢婚T通用的編程語(yǔ)言。
兩種設(shè)計(jì)方法沒(méi)有絕對(duì)的對(duì)錯(cuò),都有各自適用的場(chǎng)景,單一地采用任何一種方法都會(huì)有問(wèn)題,需要根據(jù)實(shí)際情況在快速實(shí)現(xiàn)和系統(tǒng)擴(kuò)展性之間做權(quán)衡。也正因?yàn)闆](méi)有對(duì)錯(cuò)之分,所以編輯器的圣戰(zhàn)永遠(yuǎn)也打不完。
感謝各位的閱讀,以上就是“如何理解編輯器思維與系統(tǒng)設(shè)計(jì)思想”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)如何理解編輯器思維與系統(tǒng)設(shè)計(jì)思想這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!