程序員省錢大法 - 寫腳本畫圖

在程序員的世界里,雖然別號碼農,可是相當多的時間并不是在寫代碼,而是畫圖,誰叫人是視覺動物呢。

在日常工作會經常繪制或閱讀 UML中的那些類圖,時序圖,狀態圖,以及常用的框圖,流程圖, 和思維導圖等,可用的工具也很多,比如 Visio, Gliffy, StarUml, XMind 等等,各有善長,有功能有限的免費產品,也有功能強大的收費產品。當然,我用的比較趁手的基本上都是要收費的。

其實,在程序員的世界里,更喜歡寫代碼來生成圖表,比較我最常用的

這兩個站點很好用,但是只有基本功能是免費的,高級功能是要另外收費的。其實自己基于兩個很有用的工具庫 Graphviz 和 PlantUML,自己寫一款畫圖工具,通過寫腳本來生成各種圖形是很容易的事。

這不,我用 Python Flask 框架簡單包裝了一下,搭建一個本地站點,可以很輕松的繪制各種程序員常用的圖形。

先寫一個簡單的例子,用這個站點來繪制一個思維導圖:

NIO -> Channel
NIO -> Buffer
NIO -> Selector
Buffer -> ByteBuffer
Buffer -> CharBuffer
Buffer -> MappedByteBuffer
Channel -> FileChannel
Channel -> DatagramChannel
Channel -> SocketChannel
Channel -> ServerSocketChannel

如上圖,用 python flask 框架寫一個 web 應用,再通過調用 Graphviz 支持的各種流程圖,線框圖和思維導圖,通過調用 plantuml 繪制各種 UML 圖形。

再舉幾例:

流程圖 - 網站登錄

  • 先寫幾行如下的腳本
start -> IsExceedMaxAttempts
IsExceedMaxAttempts -> Login[cond=no]
IsExceedMaxAttempts -> LockAccount[cond=yes]
LockAccount -> DisplayAlert
Login -> IsAuthorized
IsAuthorized -> GrantAccess[cond="yes"]
IsAuthorized -> IsExceedMaxAttempts[cond="no"]
GrantAccess -> end
DisplayAlert -> end

可以通過上面的 web 界面,也可以通過如下的命令行來生成圖形:

fab draw:./examples/login-flowchart.txt,./examples/login-flowchart.png

時序圖 - TCP 握手和揮手

  • 先寫一個如下的腳本
title TCP handshake
participant client
participant server
autonumber "<b>[00]"

== open ==
note right of server: LISTEN
client -> server: SYN
note left of client: SYN_SENT
note right of server: SYN_RCVD
server --> client: ACK/SYN
server -> client: ACK
note over client, server: ESTABILISHED

== close ==

client -> server: FIN
note left of client: FIN_WAIT_1
note right of server: CLOSE_WAIT
server --> client: ACK
note left of client: FIN_WAIT_2
server -> client: FIN
note right of server: LAST_ACK
note left of client: TIME_WAIT
client --> server: ACK
note right of server #FFAAAA: CLOSED


即可生成如下的圖形

狀態圖

  • 線程狀態圖
[*] --> Created: new
Created --> Ready: start
Ready --> Running: run
Running --> Ready: yield, interrupt
Running --> Waiting: wait, sleep, suspend
Waiting --> Ready: notify, resume
Running --> Terminated
Terminated --> [*]

類圖 Netty 的 Event Loop 相關類

interface EventExecutorGroup
interface ScheduledExecutorService
interface Iterable
interface EventExecutor
interface EventLoop
abstract class SingleThreadEventLoop
class EpollEventLoop
abstract class Selector
class SelectedSelectionKeySetSelector 

EventExecutorGroup --|> ScheduledExecutorService
EventExecutorGroup --|> Iterable
EventExecutor --|> EventExecutorGroup
EventLoopGroup --|> EventExecutorGroup
EventLoop --|> EventLoopGroup
SingleThreadEventLoop --|>  EventLoop
EpollEventLoop --|> SingleThreadEventLoop
NioEventLoop --|> SingleThreadEventLoop
SelectedSelectionKeySetSelector --|> Selector
NioEventLoop o-- Selector

interface EventExecutorGroup {
    EventExecutor next();
    Iterator<EventExecutor> iterator();
    Future<?> submit(Runnable task);
   <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit);
    Future<?> shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit);
    size();
}

interface EventLoopGroup  {
    next();
    ChannelFuture register(Channel channel);
    ChannelFuture register(ChannelPromise promise);
}

interface EventExecutor {
    EventExecutor next();
    EventExecutorGroup parent();
    boolean inEventLoop();
    boolean inEventLoop(Thread thread);
    <V> Promise<V> newPromise();
    <V> ProgressivePromise<V> newProgressivePromise();
    <V> Future<V> newSucceededFuture(V result);
    <V> Future<V> newFailedFuture(Throwable cause);
}

interface EventLoop {
    EventLoopGroup parent();
}

class NioEventLoop {
    private Selector selector;
    private Selector unwrappedSelector;
    private SelectedSelectionKeySet selectedKeys;
    private final SelectorProvider provider;
}

還可以舉出許多例子,詳細的搭建步驟和相關代碼請參見 https://github.com/walterfan/webdiagram

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容