圖工程化實(shí)踐)
最近一次內(nèi)部評(píng)審讓我印象特別深。某產(chǎn)品組匯報(bào)一個(gè)數(shù)據(jù)中臺(tái)項(xiàng)目PPT里放了一張系統(tǒng)架構(gòu)圖邏輯本身沒問題但那張圖我盯著看了快兩分鐘才勉強(qiáng)理出調(diào)用鏈路。問題不在內(nèi)容在diagram-design——區(qū)塊堆疊沒有層次連線的粗細(xì)含義不明核心鏈路和邊緣邏輯混在一起整張圖看起來“全對(duì)”實(shí)際“全不可讀”。這不是個(gè)例幾乎每個(gè)團(tuán)隊(duì)都有幾張這樣的圖。所以我想認(rèn)真聊聊圖表設(shè)計(jì)這件事它不是排版問題是信息架構(gòu)問題不是畫圖技巧是工程設(shè)計(jì)問題。這篇文章圍繞diagram-design展開核心思路是把畫圖從“手工拖拽排版”升級(jí)為“結(jié)構(gòu)化定義 代碼化管理”。我把一次用戶畫像系統(tǒng)的架構(gòu)圖重繪過程完整記錄下來包括信息分層的方法、工具選型的理由、從零到可交付圖的完整步驟、顏色與版式的編碼邏輯以及真實(shí)踩過的四個(gè)坑。適合三類讀者經(jīng)常需要畫流程圖、架構(gòu)圖但總被反饋“看不懂”的工程師需要把復(fù)雜技術(shù)方案畫給業(yè)務(wù)方看的技術(shù)負(fù)責(zé)人以及想用代碼方式管理圖表資產(chǎn)、告別反復(fù)調(diào)整對(duì)齊線的同學(xué)。1. 別再手工拖拽“畫”圖了把圖表當(dāng)成工程來設(shè)計(jì)先說一個(gè)反直覺的結(jié)論絕大多數(shù)難看的架構(gòu)圖問題不在配色、圖標(biāo)或?qū)徝蓝谧髡吒静恢雷约合氡磉_(dá)什么。手工拖拽工具給了太多自由度反而讓人繞過了最重要的思考——這張圖的核心信息是什么給誰看看完要得到什么結(jié)論。diagram-design的第一步是把圖當(dāng)成一個(gè)工程對(duì)象來設(shè)計(jì)而不是當(dāng)成一張畫布來填充。1.1 一張好圖的四個(gè)判斷標(biāo)準(zhǔn)我給自己定了一套標(biāo)準(zhǔn)每次畫完圖都會(huì)逐條自檢你也可以直接拿過去用。第一意圖單一。一張圖只回答一個(gè)問題?!跋到y(tǒng)整體拓?fù)洹薄昂诵恼{(diào)用鏈路”“異常處理時(shí)序”這三個(gè)問題不應(yīng)該出現(xiàn)在同一張圖里。第二層次清楚。圖里有主語、謂語、賓語。主語是模塊和系統(tǒng)謂語是連線上的動(dòng)詞調(diào)用、寫入、訂閱、返回賓語是數(shù)據(jù)和狀態(tài)。讀者掃一眼就能分清誰在主動(dòng)、誰在被調(diào)。第三密度適中。一個(gè)區(qū)塊里塞超過七個(gè)節(jié)點(diǎn)基本就是可讀性的臨界線。超過這個(gè)數(shù)要么拆分要么分層。第四可維護(hù)。圖源文件能進(jìn)版本庫能diff評(píng)審改一處不會(huì)牽一發(fā)動(dòng)全身。文本化描述天然滿足這一點(diǎn)拖拽型畫布基本做不到。這四個(gè)標(biāo)準(zhǔn)不是審美偏好是可以執(zhí)行的設(shè)計(jì)約束。我見過很多團(tuán)隊(duì)圖庫里有幾十張“一次性圖”每次方案變更都要從頭重畫原因就是最開始設(shè)計(jì)時(shí)沒把可維護(hù)性放進(jìn)去。把圖當(dāng)工程意味著每一次改動(dòng)都要低成本、可追溯。1.2 為什么我最終選了文本化定義而不是畫布拖拽畫架構(gòu)圖的主流路線有三大類畫布拖拽類比如各類在線白板、專業(yè)繪圖類比如帶自動(dòng)布局的桌面軟件、文本定義類用代碼描述結(jié)構(gòu)再由引擎生成圖形。我最終選了文本定義類方案核心原因是它把“畫圖”變成了“寫代碼”。類似白板的產(chǎn)品優(yōu)點(diǎn)是上手快但致命弱點(diǎn)是沒有任何底層規(guī)則約束節(jié)點(diǎn)之間的邏輯關(guān)系需要人為保證。大圖上對(duì)齊靠手線交叉靠手動(dòng)繞開改一處微調(diào)半天。更麻煩的是這種文件封閉在平臺(tái)里沒辦法用git做版本對(duì)比。專業(yè)繪圖類在自動(dòng)布局上做得好但一旦圖大起來布局引擎為了讓線不交叉會(huì)瘋狂壓縮間距最后生成一張“看起來整齊、實(shí)際讀不動(dòng)”的密鋪圖。文本定義類有一個(gè)根本性優(yōu)勢(shì)圖的邏輯結(jié)構(gòu)被顯式表達(dá)而不是隱式藏在坐標(biāo)和像素里。它把精力分配到“節(jié)點(diǎn)之間到底是什么關(guān)系”上而不是“那條線畫在哪”上。而且文本文件天然適合版本管理任何改動(dòng)都可以做diff評(píng)審。這個(gè)特點(diǎn)在多人協(xié)作、方案迭代的場景下太重要了。我鎖定的具體方案是PlantUML加VS Code插件配合本地渲染。之所以選它而不是同類工具理由有三個(gè)語法負(fù)擔(dān)極低十幾分鐘能上手可以引入分層設(shè)計(jì)思想和布局策略來管理復(fù)雜圖不用手動(dòng)拖拽渲染引擎可以本地跑完全不依賴在線服務(wù)。下面所有示例都基于這套方案方法論完全可以遷移到其他文本繪圖工具。2. 先畫邏輯再畫線條diagram-design的信息架構(gòu)與分層很多人畫圖的第一動(dòng)作是打開工具拖一個(gè)矩形出來這是完全反了。正確的順序是先做信息架構(gòu)再談視覺呈現(xiàn)。我要重畫的那張用戶畫像系統(tǒng)架構(gòu)圖原始版本把所有內(nèi)容塞在一張圖里從數(shù)據(jù)采集到數(shù)倉清洗從離線標(biāo)簽到實(shí)時(shí)規(guī)則從對(duì)外API到前端展示十幾條鏈路交錯(cuò)在一起根本沒法讀。我做的第一件事是停下來想清楚信息層次。2.1 頂層視角一張圖只回答一個(gè)問題我給重繪定了一個(gè)原則一張圖只回答一個(gè)問題。最終決定先畫“核心調(diào)用鏈路圖”回答的問題是運(yùn)營同學(xué)發(fā)起的畫像查詢請(qǐng)求經(jīng)過哪些組件、拿到什么數(shù)據(jù)、最終怎么返回。至于數(shù)據(jù)采集、任務(wù)調(diào)度、權(quán)限控制全部不在這張圖的討論范圍內(nèi)。確定問題之后主體才清晰。在這張圖的設(shè)計(jì)里主語有三個(gè)發(fā)起者、中間服務(wù)、數(shù)據(jù)來源。謂語是同一條鏈路上不同層級(jí)的處理動(dòng)作賓語則統(tǒng)一為“請(qǐng)求”和“數(shù)據(jù)”。明確了主語謂語賓語畫出來的圖天然有方向感。這一步花了整整一個(gè)下午比畫圖本身耗時(shí)還久但最終結(jié)果是值得的。這里分享一個(gè)很有效的辦法在新建一個(gè)圖源文件的同時(shí)先寫一行偽代碼類似這種。運(yùn)營同學(xué)查詢畫像 -- API網(wǎng)關(guān)鑒權(quán) -- 畫像服務(wù)拼裝 -- 標(biāo)簽倉庫讀取 -- 返回渲染畫完圖以后再對(duì)照這行偽代碼如果圖里的主干鏈路和偽代碼不一致說明畫偏了。許多架構(gòu)圖畫完像蜘蛛網(wǎng)根因就是主干思想不明確副線畫太多。2.2 逐層拆解從系統(tǒng)邊界到模塊內(nèi)部一張圖一個(gè)主問題不代表所有信息都?jí)涸谝粋€(gè)主圖層級(jí)。信息架構(gòu)的第二步是“分疊”設(shè)計(jì)。我會(huì)把一張大型圖拆成三個(gè)視角層系統(tǒng)拓?fù)鋵印⒛K交互層、內(nèi)部細(xì)節(jié)層。系統(tǒng)拓?fù)鋵踊卮稹坝心男┫到y(tǒng)、邊界在哪”用泳道或大分區(qū)框表達(dá)。模塊交互層回答“系統(tǒng)之間怎么協(xié)作”用有方向的帶標(biāo)簽連線表達(dá)。內(nèi)部細(xì)節(jié)層回答“模塊內(nèi)部怎么處理”這是時(shí)序圖或活動(dòng)圖的專場不該出現(xiàn)在系統(tǒng)拓?fù)鋱D里。用戶畫像系統(tǒng)重繪時(shí)我把系統(tǒng)拓?fù)浞诺谝粡埬K交互放第二張規(guī)則引擎內(nèi)部的狀態(tài)流轉(zhuǎn)單獨(dú)用一張活動(dòng)圖。第一張圖從十幾條交錯(cuò)鏈路變成四個(gè)分區(qū)上游數(shù)據(jù)區(qū)、畫像存儲(chǔ)與計(jì)算區(qū)、對(duì)外服務(wù)區(qū)、業(yè)務(wù)調(diào)用方。信息密度降了辨識(shí)度大幅上升。還有一個(gè)實(shí)操點(diǎn)是分區(qū)邊界的表達(dá)。同一張圖里可以有不同類型的容器系統(tǒng)邊界用粗框模塊分組用虛線框某個(gè)組件的局部放大用淺色底框。在PlantUML里對(duì)應(yīng)package、rectangle和component三類容器的組合。下圖是一個(gè)基礎(chǔ)分層示例。startuml !pragma layout smetana title 用戶畫像系統(tǒng)核心調(diào)用鏈路簡化 actor 運(yùn)營同學(xué) as op database 數(shù)倉寬表 as dw boundary 畫像服務(wù) as svc entity 標(biāo)簽倉庫 as tag entity 規(guī)則引擎 as rule control API Gateway as gw op -- gw : 查詢請(qǐng)求 gw -- svc : 校驗(yàn)并轉(zhuǎn)發(fā) svc -- tag : 讀取標(biāo)簽集合 svc -- rule : 執(zhí)行實(shí)時(shí)規(guī)則 rule -- dw : 拉取行為寬表 rule -- svc : 返回打分結(jié)果 svc -- op : 返回畫像結(jié)果 legend right 實(shí)線表示一次同步調(diào)用 虛線表示批量離線任務(wù) endlegend enduml這段代碼產(chǎn)出的圖主干就是一條清晰鏈路沒有多余的交叉。讀者順著箭頭的方向讀一遍整張圖的核心邏輯就清楚了。這就是“先畫邏輯再畫線條”的實(shí)際效果。2.3 連線是信息流不是裝飾線架構(gòu)圖上最容易被忽視也最常被濫用的要素是連線。很多人把線當(dāng)成“這兩個(gè)模塊有關(guān)系”的模糊表達(dá)結(jié)果一張圖上全是線等于沒有線。線必須有語義。在設(shè)計(jì)這個(gè)步驟我用三類線同步調(diào)用用帶箭頭實(shí)線線旁動(dòng)詞標(biāo)注批量數(shù)據(jù)流轉(zhuǎn)用帶箭頭虛線標(biāo)注“T1”之類的頻率說明異步消息用無箭頭粗線標(biāo)注消息主題。這三種線混在一張圖里沒問題但前提是必須在圖例里說明否則讀者只能猜。畫線時(shí)還有一個(gè)容易被忽略的細(xì)節(jié)線的方向要和閱讀順序一致。人的閱讀習(xí)慣是從左上到右下主干鏈路盡量走這個(gè)方向。如果畫的時(shí)候發(fā)現(xiàn)箭頭大量向上或向左說明主干方向設(shè)計(jì)有問題需要調(diào)整。我在重繪圖里特意刪掉了原圖一半的線。刪完以后整張圖清爽了很多因?yàn)槭O碌拿織l線都必須回答一個(gè)重要問題為什么要連線。如果你說不清這條線存在的理由它就不該出現(xiàn)在圖上。3. 用PlantUML跑通第一版從框架到可用圖的生產(chǎn)過程信息架構(gòu)做完才進(jìn)入真正的產(chǎn)出階段。這一節(jié)把從零到第一版可交付圖的完整過程拆開講包括環(huán)境搭建、語法細(xì)節(jié)、注釋規(guī)范。你不用關(guān)心具體工具名稱方法本身可復(fù)用。3.1 環(huán)境準(zhǔn)備文本繪圖如何做到“寫完即渲染”文本繪圖方案的環(huán)境比想象中輕量。核心是三件事文本編輯器提供語法高亮和預(yù)覽渲染環(huán)境負(fù)責(zé)把代碼轉(zhuǎn)成圖形版本庫管理圖源文件。實(shí)操中我用VS Code加官方PlantUML插件插件自動(dòng)識(shí)別.puml后綴文件保存時(shí)快捷鍵觸發(fā)渲染。首次使用需要讓渲染引擎跑起來本地有Java環(huán)境可以走本地jar包方式我推薦用Docker方式跑渲染服務(wù)省去本機(jī)裝Java的麻煩團(tuán)隊(duì)內(nèi)還能共用同一套渲染環(huán)境避免版本不一致導(dǎo)致同一段代碼渲染結(jié)果不同。跑通環(huán)境以后我會(huì)在倉庫里建一個(gè)diagrams目錄按項(xiàng)目分文件夾每個(gè)圖源文件給一個(gè)有意義的名字比如user-profile-core-call.puml。圖源文件像代碼一樣進(jìn)版本庫這是整套方案能落地的基石。每一個(gè)改動(dòng)都能被追蹤、被復(fù)查出問題能回退。3.2 第一版繪制聲明結(jié)構(gòu)、分層區(qū)塊與交互語義畫圖時(shí)先聲明結(jié)構(gòu)再調(diào)整細(xì)節(jié)。第一版的第一步是定義參與方包括四種常見元素類型actor人或者外部系統(tǒng)、control控制節(jié)點(diǎn)、entity數(shù)據(jù)實(shí)體、database存儲(chǔ)它們?cè)阡秩竞笥忻黠@的外觀區(qū)別讀者能從視覺差異反推語義差異。第二步是分組。package定義大分區(qū)component定義小模塊。用戶畫像系統(tǒng)的四個(gè)分區(qū)對(duì)應(yīng)四行聲明package 數(shù)據(jù)接入與數(shù)倉層 as data_zone { component 行為日志采集 as collect database 數(shù)倉寬表 as dw } package 畫像計(jì)算層 as compute_zone { component 標(biāo)簽倉庫 as tag component 實(shí)時(shí)規(guī)則引擎 as rule } package 服務(wù)交互層 as service_zone { control API Gateway as gw boundary 畫像服務(wù) as svc } package 業(yè)務(wù)調(diào)用層 as biz_zone { actor 運(yùn)營同學(xué) as op }注意我沒有把所有元素一股腦寫在一行里。分區(qū)名和變量名分別定義后面連線用變量名這樣即使在多達(dá)幾十行的源文件里調(diào)整結(jié)構(gòu)也不用手動(dòng)改一大段布局代碼。第三步是連線原則是動(dòng)詞驅(qū)動(dòng)。連線時(shí)始終考慮箭頭上標(biāo)注的動(dòng)詞邊寫邊問自己這兩個(gè)節(jié)點(diǎn)之間的關(guān)系到底是什么。如果找不到合適的動(dòng)詞大概率這兩個(gè)節(jié)點(diǎn)本來就不該直接相連。3.3 讓圖可以被“讀”標(biāo)題、圖例與解釋區(qū)設(shè)計(jì)第一版跑通后我會(huì)花同樣多的時(shí)間做“可讀性裝配”。這一步包含三個(gè)固定動(dòng)作第一給圖加title。標(biāo)題必須是一句完整的話而不是一個(gè)名詞。header用戶畫像系統(tǒng)核心調(diào)用鏈路簡化比畫像系統(tǒng)有用得多。讀者看到標(biāo)題就知道這張圖要說明什么。第二加legend圖例。圖里有幾種線、幾種顏色、幾種形態(tài)都要在legend里說明。沒有圖例的架構(gòu)圖一律視為未完成品。第三在圖源文件頂部用注釋描述適用范圍。這段注釋不渲染在圖上但寫清楚這張圖能回答什么、不回答什么、最新修改日期、對(duì)應(yīng)方案版本。對(duì)后續(xù)維護(hù)非常重要。還有一個(gè)容易被忽略的細(xì)節(jié)節(jié)點(diǎn)名稱默認(rèn)用英文用alias別名顯示中文兩者的職責(zé)分開。節(jié)點(diǎn)內(nèi)部名稱是標(biāo)識(shí)符顯示的標(biāo)簽是alias中文字符串。這樣后續(xù)做自動(dòng)化的關(guān)聯(lián)分析、腳本批量替換都能穩(wěn)定進(jìn)行不會(huì)因?yàn)橹形牟町悓?dǎo)致匹配失敗。4. 顏色與版式把“視覺修飾”變成“信息編碼”畫到這一步圖已經(jīng)能讀、能用了。但要讓讀者在掃一眼時(shí)正確抓住重點(diǎn)而不是被所有信息平均地砸在臉上需要顏色和版式來幫忙。這一節(jié)不是講審美是講如何用視覺手段做信息編碼。4.1 一套可復(fù)用的配色規(guī)則三類顏色信息一開始我也喜歡給不同模塊配不同顏色紅、藍(lán)、綠、紫各來一套渲染出來五彩斑斕信息卻更亂。后來我總結(jié)出一套規(guī)則簡單、通用、經(jīng)得起推敲中性色白、淺灰打底表示容器、分組、背景元素。主色類藍(lán)、青用來標(biāo)記核心鏈路節(jié)點(diǎn)。強(qiáng)調(diào)類深橙、黃用來標(biāo)記異常分支、告警路徑、需要讀者注意的關(guān)鍵判斷點(diǎn)。區(qū)塊分隔色淺綠、淺灰用來標(biāo)記不同系統(tǒng)邊界。這套體系的核心邏輯是顏色不是裝飾是對(duì)信息做優(yōu)先級(jí)編碼。讀者看圖時(shí)注意力會(huì)習(xí)慣性地先被高飽和度顏色吸引所以必須把高飽和度留給最重要信息而不是大面積使用。在PlantUML里每個(gè)skinparam和節(jié)點(diǎn)上的底色配置回報(bào)率最高的兩個(gè)控制在視覺縱深上??v深的第一層是容器分區(qū)用淺色底紋框出大邊界第二層是節(jié)點(diǎn)本身用白底加邊框第三層才是用主色強(qiáng)調(diào)的核心路徑。4.2 分層排版三原則一字排開、分層標(biāo)注、模塊化注釋分區(qū)排版有一組穩(wěn)定可行的操作性原則。原則一是同層元素一字排開設(shè)計(jì)同層級(jí)的節(jié)點(diǎn)盡量在視覺上平齊同行同高。原則二是層級(jí)用包絡(luò)框表達(dá)同一系統(tǒng)下不同子模塊的關(guān)系用虛線框包裹避免跨層跨系統(tǒng)的連線。原則三是模塊內(nèi)注釋放右上角源文件的注釋要跟上模塊結(jié)構(gòu)而不是散落在無關(guān)位置。間距在整體版式中經(jīng)常被忽視。細(xì)膩形態(tài)需要刻意制造留白模塊與模塊之間至少保留兩組節(jié)點(diǎn)寬度的間距連線上增加足夠圓角與彎曲。因?yàn)閳D不是給機(jī)器看的緊湊代碼是給人看的思維地圖。4.3 中文渲染與字體選擇的實(shí)際坑中文方案在一開始渲染會(huì)遇到一個(gè)現(xiàn)實(shí)問題默認(rèn)字體在環(huán)境里可能不支持中文渲染出來的方塊文本完全不可讀。處理方式很直接在文件開頭顯式聲明支持中文的字體。skinparam defaultFontName Noto Sans CJK SC還有個(gè)常踩的坑是換行。有同學(xué)在Rect里直接寫整段中文發(fā)現(xiàn)渲染結(jié)果亂成一團(tuán)。真相是PlantUML的矩形節(jié)點(diǎn)內(nèi)換行必須顯式用\n而非直接回車。component 實(shí)時(shí)規(guī)則引擎\n延遲 500ms as rule這個(gè)組合可以做出更規(guī)整的視覺信息編碼主名稱加副說明層次充分區(qū)塊邊界清楚明確分劃出了通用區(qū)域內(nèi)文字的對(duì)齊關(guān)系。5. 跑通之后一定會(huì)踩的坑四類高頻問題排查真實(shí)項(xiàng)目里部署這套方案會(huì)遇到一些和期待不符的現(xiàn)象。我把最常見的四類問題還原成完整排查過程下次遇到可以直接對(duì)照記錄。5.1 布局引擎的選擇差異與失控生成第一版時(shí)我用了默認(rèn)布局引擎圖的節(jié)點(diǎn)一多線條交叉嚴(yán)重完全沒辦法用。后來換用新布局引擎啟用命令才解決。這個(gè)引擎確實(shí)顯著改善了復(fù)雜圖中的交叉但它并非全自動(dòng)的銀彈需要使用語義分組配合它就是前文講的package劃分。即先分區(qū)再讓布局引擎在分區(qū)內(nèi)排布最后整體調(diào)整。這個(gè)組合出來的效果遠(yuǎn)遠(yuǎn)好于只靠自動(dòng)布局。5.2 局部樣式改改不生效、優(yōu)先級(jí)混亂中段調(diào)整環(huán)節(jié)容易遇到的問題是我只改了某個(gè)節(jié)點(diǎn)顏色結(jié)果另一組同名組件全都跟著變色。根因在于PlantUML中一個(gè)元素的樣式定義既可能來自skinparam全局配置也可能來自文件內(nèi)嵌的局部配置局部優(yōu)先級(jí)更高但會(huì)繼承全局默認(rèn)值。排查思路是先審視skinparam默認(rèn)值再檢查局部配置是否有拼寫錯(cuò)誤最后確認(rèn)是否被繼承屬性覆蓋。需要高度注意局部變量名與元素名的對(duì)應(yīng)關(guān)系。5.3 圖一放大就發(fā)虛、無法用作正式文檔把渲染輸出插入正式文檔時(shí)會(huì)出現(xiàn)圖太糊、線條邊緣發(fā)虛的問題。原因是默認(rèn)輸出分辨率只有96DPI。將導(dǎo)出值開到足夠高的密度如2048像素寬能解決。不同環(huán)境的導(dǎo)出選項(xiàng)不同建議優(yōu)先采用高分辨率PNG或矢量SVG輸出。矢量格式后續(xù)在任何地方縮放都不會(huì)損失清晰度。5.4 一次改圖引發(fā)的“連鎖崩潰”團(tuán)隊(duì)協(xié)作改圖時(shí)最常見的狀況是某人加了一組節(jié)點(diǎn)后原本整潔的布局整個(gè)亂掉被迫手動(dòng)拉很久。排查后發(fā)現(xiàn)根因是新增節(jié)點(diǎn)沒有掛靠到具體分區(qū)給了布局引擎錯(cuò)誤信息輸入。它只好把節(jié)點(diǎn)作為孤立區(qū)域處理重組到任意位置。修復(fù)方式并不復(fù)雜所有新增元素一律先放進(jìn)package區(qū)再連線。把每條連線都畫到對(duì)應(yīng)的組成員上而不是畫在組外。除了這些技術(shù)坑還有一個(gè)貫穿始終的心法值得專門強(qiáng)調(diào)一張架構(gòu)圖的第一個(gè)讀者是兩周后的自己。剛畫完的人永遠(yuǎn)覺得圖清晰是因?yàn)槟X子里裝了完整上下文。兩周后回來看只能憑圖上的信息和構(gòu)圖還原當(dāng)時(shí)的判斷。凡是沒法做到這一步的圖都還不到交付標(biāo)準(zhǔn)。6. 沉淀成團(tuán)隊(duì)習(xí)慣從一張圖到一套圖庫單張圖畫得再好如果沒有沉淀機(jī)制下一次還得從零開始。把diagram-design推廣到團(tuán)隊(duì)層面之后我逐步搭建了一套輕量圖庫體系。這套做法經(jīng)過時(shí)間檢驗(yàn)?zāi)苤苯映?.1 建立圖庫結(jié)構(gòu)模板、組件、風(fēng)格約定圖庫我按三層維護(hù)。底層是素材庫放常用節(jié)點(diǎn)聲明片段、配色主題文件、公共組件定義案例。模板短語在第二層我跑通了“頂層設(shè)計(jì)-鏈路-最關(guān)鍵步驟”三段模板新建圖的時(shí)候直接復(fù)制模板骨架。頂層是正式圖庫每一張已經(jīng)評(píng)審過的圖源文件都附帶一行修改說明、適用范圍、最后更新日期。三層結(jié)構(gòu)能保證素材和正式圖分離每個(gè)人都能安全復(fù)用模板不會(huì)誤改正式資產(chǎn)。6.2 評(píng)審一張圖比畫一張圖更重要團(tuán)隊(duì)圖庫里總會(huì)出現(xiàn)風(fēng)格完全不一致的圖根本原因是評(píng)審缺位。我堅(jiān)持一條規(guī)則架構(gòu)圖必須進(jìn)入設(shè)計(jì)評(píng)審跟代碼評(píng)審一樣的流程。評(píng)審時(shí)重點(diǎn)檢查四個(gè)點(diǎn)這張圖是否真的只回答一個(gè)問題每條線是否有明確語義且足夠充分舉證顏色是否遵守統(tǒng)一的配色約定是否配置了標(biāo)題、圖例、注釋、作者與日期信息。這四條里面最容易被挑戰(zhàn)的是第二條一條線說不清語義基本會(huì)當(dāng)場打回。除了評(píng)審機(jī)制每周模板設(shè)計(jì)時(shí)間也值得專門安排一個(gè)時(shí)段每人挑一張自己近期最滿意的圖和最不滿意的一張圖一起診斷。對(duì)于不滿意的那張圖只討論三個(gè)問題第一眼不知道看哪、渲染后連線過雜還是標(biāo)簽語義不完整這比抽象聊“好看不好看”有療效。6.3 從圖庫到方法庫讓經(jīng)驗(yàn)不斷滾進(jìn)來運(yùn)行一段時(shí)間后圖庫的下一步演進(jìn)是沉淀方法庫。方法庫里不再存圖存的是判斷依據(jù)。比如“一個(gè)區(qū)塊最多放七個(gè)節(jié)點(diǎn)否則分拆”“主鏈路用實(shí)線、批量任務(wù)用虛線、異步消息用粗線”“核心節(jié)點(diǎn)用主色異常路徑用強(qiáng)調(diào)色其余一律中性色”。這些判斷依據(jù)來自對(duì)生成圖的反復(fù)思考一旦沉淀下來就能脫離具體工具而獨(dú)立存在。無論將來用哪個(gè)工具畫圖這些標(biāo)準(zhǔn)都繼續(xù)適用。這也正是diagram-design最深的含義把一次畫圖變成一次嚴(yán)謹(jǐn)?shù)慕Y(jié)構(gòu)設(shè)計(jì)。而我越來越確信嚴(yán)謹(jǐn)?shù)慕Y(jié)構(gòu)設(shè)計(jì)才是好圖真正的捷徑。