作者 | Alex Ellis
譯者 | 平川
策劃 | 閆園園
本文最初發(fā)布于 Alex Ellis 的個人博客。
有一天,我正在閱讀關于個人電腦和桌面 GUI 發(fā)展的內(nèi)容,我就想,我們都已經(jīng)非常習慣個人電腦“桌面“這個類比。我們把文件放在文件夾里,并把它們放在桌面上。這個過程有很多物理動作發(fā)生。
人類非常善于理解空間,尤其是在記憶物理空間的時候,這讓我聯(lián)想到了我們通常如何將代碼可視化。在思考和可視化代碼的時候,有沒有什么好的方法可以利用這一點?
如何可視化代碼?
這讓我想到了我往往如何可視化代碼,有點難以描述。我認為,它通常以不同的方式存在于我的腦海中,這取決于抽象和特殊性水平,而且同時存在若干不同方式的組合。根據(jù)需要,我可以很好地在它們之間切換,特別是當我對代碼庫非常熟悉的時候。例如,當我想象各種微服務之間的交互時,在每個服務的周圍畫個大方框是很有幫助的,把每個服務視為一個大的工作單元,彼此之間通過 RPC 交互。
一個簡單的面向微服務的汽車租賃服務架構圖,以及代表一條執(zhí)行路徑的分布式跟蹤。
另一方面,如果對于計算機如何讀取我給它的東西,我想知道微末的細節(jié),那么把所有東西放大到物理內(nèi)存表示是有幫助的。
我曾經(jīng)做過的一個 Google Sheets 頁的截圖,上面有內(nèi)存地址和匯編指令。這對于非常仔細地了解整個過程很有幫助。
幸運的是,我把大部分時間都花在了中間的某個地方,在閱讀實際的代碼(比匯編高級),把大塊的代碼作為一個個大的單元來思考,和研究架構圖及系統(tǒng)間通信之間做一些平衡。即使是代碼本身也已經(jīng)有了很多物理關系;想想目錄路徑、命名空間、行縮進以及代碼行的線性排序。
這些可視化的效果如何?
對于這個問題,我考慮了一些不同的可視化技術,每一種技術都有不同的應用場景。考慮一下下面這個不完全的清單:
架構圖
依賴圖
分布式跟蹤
序列圖
類圖
打印語句
火焰圖
閱讀源代碼
怎么對它們進行比較呢?首先,似乎有一個天然的抽象等級軸線,從低級的代碼閱讀到高級的架構圖。似乎還有一些其他的軸線,我們也可以對它們進行排序。
也許我們可以根據(jù)它們在多大程度上代表了更大的系統(tǒng)來對它們進行排名?架構圖在這方面做得很好,但火焰圖只能代表單個執(zhí)行路徑。也許是變化的頻率?這是一個有趣的問題,雖然源代碼經(jīng)常變,但架構圖(有望)保持穩(wěn)定。
讓我們想一下,可視化如何很好地表示整個系統(tǒng)實際的代碼執(zhí)行情況呢?在這種情況下,高級的架構圖得分也許不會很高,因為它抽象掉了服務框內(nèi)的許多細節(jié)。分布式跟蹤可以做得更好,不過具體程度取決于有多少個跟蹤點。類圖雖然有助于可視化類之間的關系,但可能并不表示實際的路徑?;鹧鎴D可以顯示清晰的執(zhí)行路徑,但只能顯示單條代碼路徑,而不能為更大的系統(tǒng)提供可見性。
畫到圖上可能會像下面這樣,不過上面的這些點表示為一個范圍可能更好:
這讓我思考,右上角的部分會是什么樣子。一個能讓我們洞察細節(jié)的、有用的可視化該是什么樣子?有沒有一種方法可以在較低的層次上,將整個系統(tǒng)的路徑可視化?
如果我們也使用空間會是什么樣子?
看圖的感覺仍然像看地圖。在那一刻,你把在代碼中看到的東西在空間上轉(zhuǎn)化為圖表,就像你在一個不熟悉的地方用地圖確定方向。就像電腦上的東西,我們用了桌面隱喻一樣,我想知道是否有另一種方式將代碼可視化為實際存在的東西,以便讓翻譯過程變得更容易。
如果我們用“玩具型可視化(toy visualization)”在物理空間中表示代碼,會怎么樣?
看下面這個基本的例子,我們有一個 Counter 類,它有一個私有的 count_ 變量并提供了各種訪問方法。也許它會在一個簡單的 main 函數(shù)中被訪問,做一些計數(shù)。
如果我們把代碼的不同部分表示為三維結(jié)構,會怎么樣?如果我們把 Counter 類表示為一個大房間,墻上寫著咒語,會怎么樣?你可以想象代碼的可能路徑,變量和它們所代表的事物之間的聯(lián)系,就像下圖中的粉紅線:
我們可以從中看到什么?首先,作為私有變量,count_ 的用法顯然沒有什么不當,因為沒有任何粉紅線從它那里離開房間。公共方法也很清楚,它們與房間外的事物有粉紅色的連接。
更有趣的是,這個房間與另一個房間相連,會是什么樣子?main 函數(shù)可以是另一個房間,其符咒線也做了相應的連接:
現(xiàn)在,我們可以跨房間對話了;在 main 函數(shù)調(diào)用 counter.reset() 的地方,我們可以有一個從調(diào)用者 main 到被調(diào)用者 Counter 類的連接。你甚至可以想象有一個調(diào)試器單步遍歷這個過程,觀察這條線路上的參數(shù)和返回值。想象一下,我們可以放大不同的區(qū)域來查看本地狀態(tài)和數(shù)值,然后沿著調(diào)用路徑返回到活動區(qū)域。
這有用嗎?
像這樣的東西有用嗎?我不確定。用這樣的方式走查一個熟悉的代碼庫會很有趣,特別是當你能在 3D 表示(或是 VR 環(huán)境)中做空間探索,并可以根據(jù)需要縮小和放大時。當?shù)谝淮翁剿饕粋€新的代碼庫,查看事物之間的連接關系時,不知道它是否會特別有用。不過,我確實處理過一些代碼庫,如果這樣看會非常嚇人。我很想看看這樣看會有什么不同,每新引入一個類,這兒那兒就會引入新的連接。
話雖如此,我認為在制作這樣的東西時,你至少會遇到以下問題:
復雜的代碼很難推理。把意大利面代碼中的意大利面可視化可謂大快人心,但是對于非常復雜的代碼來說,這樣做不知道會有多繁瑣?
如何表示出像線程同時執(zhí)行這樣的東西?
如何表示是引用傳遞而不是值傳遞?
如何表示異步工作?如何表示遞歸?房間一直嵌套下去?
如何防止里面的東西變得陳舊和過時?至少,這個需要能夠自動生成。
問題
有幾個考量因素使這個問題變得棘手。一個是物理位置的變化比代碼的變化耗時通常長得多。使用熟悉的物理位置作為記憶宮殿,一部分原因是它在你的記憶中每次出現(xiàn)都是一樣的。如果你在記憶一副撲克牌,你可以把梅花 A 暫時存放在櫥柜門后面,下次你需要存放撲克牌時,櫥柜門仍然在那。
如果你的代碼庫經(jīng)常變化,反映事物空間布局的地圖就可能會發(fā)生變化,不管這些地圖是 3D 生成的還是純意識的。這就像回到一個你曾經(jīng)熟悉的地方,想象一下,不只是地標變了,路也改道了。即使我們天生具有記憶空間事物的天賦,如果那個空間發(fā)生了變化,如果我們不得不重新學習,我們還能從空間可視化受益嗎?
看看這樣的東西對于探索一個新代碼庫(就像使用地圖探索一座新的城市),以及隨著時間推移再次回到該代碼庫(就像離開很長時間后回到自己的家鄉(xiāng)),有多大幫助,這會很有趣。
代碼可視化項目
我對這一領域的數(shù)據(jù)可視化不是很熟悉(其他領域的也不熟悉),但經(jīng)過簡單的搜索(也就是 30 分鐘的 Google 搜索),我發(fā)現(xiàn)有幾個項目似乎在做類似的事情:
SoftVis3D:其中的“代碼城市”視圖提供了項目層次結(jié)構的可視化。
Code Park:一款新的 3D 代碼可視化工具(2017),“在類似三維游戲的環(huán)境中可視化代碼庫”,其中,代碼被表示為 "代碼室",代碼在墻上(現(xiàn)在讀到這個,感覺和我的想法非常類似)。
使用 3D-Flythrough 實現(xiàn)代碼結(jié)構可視化(2016),提供空間隱喻和第一人稱代碼探索。
Primitive:一家 VR 合作初創(chuàng)公司,擁有矩陣式的“沉浸式開發(fā)環(huán)境”,包括“面向 3D 視覺分析軟件的新工具”。
下面是讀者指出的一些項目:
AppMap:一個自動化代碼分析工具,包括依賴關系圖和跟蹤視圖。
plurid:一個用于在三維可探索結(jié)構中可視化和調(diào)試代碼的框架。
fsn(文件管理器):一個實驗性的應用程序,支持以 3D 方式查看文件系統(tǒng)(出現(xiàn)在 Jurassic Park 中)。
如果你了解到其他類似的項目,歡迎和我聯(lián)系,我非常樂意聽到更多這樣的項目!
有趣的想象
顯然,這個概念并不是什么突破性的東西,但我認為,對于我們使用的工具,這是一個有趣的思考方式,重要的是,我們?nèi)绾巫龅酶谩R欢ㄓ懈玫姆椒ù嬖?,設想下它們可能的樣子會很有趣。
查看英文原文:
https://alexanderell.is/posts/visualizing-code/?
關鍵詞: 如何將你的代碼可視化