程序员难免要经常画流程图,状态图,时序图等。以前经常用 visio
画,经常为矩形画多大,摆放在哪等问题费脑筋。

有时候修改文字后,为了较好的显示效果不得不再去修改图形。

今天介绍的工具是如何使用PlantUML 的插件画流程图,状态图,时序图等。这是一种程序员看了就会爱上的画图方式:自然,高效。

什么是 PlantUML

PlantUML 是一个画图脚本语言,用它可以快速地画出:

类图:http://plantuml.com/class-diagram
流程图:http://plantuml.com/activity-diagram-beta
时序图:http://plantuml.com/sequence-diagram
用例图:http://plantuml.com/use-case-diagram
状态图:http://plantuml.com/state-diagram
组件图:http://plantuml.com/component-diagram

1. 类图

案例1:

@startuml

abstract class AbstractList
abstract AbstractCollection
interface List
interface Collection

List <|-- AbstractList
Collection <|-- AbstractCollection

Collection <|- List
AbstractCollection <|- AbstractList
AbstractList <|-- ArrayList

class ArrayList {
Object[] elementData
size()
}

enum TimeUnit {
DAYS
HOURS
MINUTES
}

@enduml

案例2:

    @startuml
    class Track
    class Media
    class Trip{
       String tripID;
       String tracks;
       String medias;
    }
    Trip --> Track
    Trip --> Media
    
    interface ITripTrackCollection{
        void start();
        void stop();
        void pause();
        void destory();
    }
    class TripTrackCollection implements ITripTrackCollection{
        Vector<LocationInfo> mLocations;
        ExtcutorService mVecoterThread;
        ScheduledExecutorService mDatabaseThread;
    }
    
    class TrackCollectService extends Service implements ITripTrackCollection{
        TripTrackCollection TripTrackCollection;
    }
    TrackCollectService -->TripTrackCollection
    @enduml

2. 流程图

案例1:

    @startuml
    (*)  --> "check input"
    If "input is verbose" then
    --> [Yes] "turn on verbosity"
    --> "run command"
    else
    --> "run command"
    Endif
    -->(*)
    @enduml

案例2:

    start
    :"步骤1处理";
    :"步骤2处理";
    if ("条件1判断") then (true)
        :条件1成立时执行的动作;
        if ("分支条件2判断") then (no)
            :"条件2不成立时执行的动作";
        else
            if ("条件3判断") then (yes)
                :"条件3成立时的动作";
            else (no)
                :"条件3不成立时的动作";
            endif
        endif
        :"顺序步骤3处理";
    endif
    
    if ("条件4判断") then (yes)
    :"条件4成立的动作";
    else
        if ("条件5判断") then (yes)
            :"条件5成立时的动作";
        else (no)
            :"条件5不成立时的动作";
        endif
    endif
    stop
    @enduml

3.时序图

案例1:

    @startuml
    Alice -> Bob: Authentication Request
    Bob --> Alice: Authentication Response
    
    Alice -> Bob: Another authentication Request
    Alice <-- Bob: another authentication Response
    @enduml

案例2:

    @startuml
    title Android Broadcast procedure
    participant Activity #Lime
    participant ContextWrapper #Cyan
    participant ContextImpl #Cyan
    participant ActivityManagerService #Cyan
    participant ActivityStackSupervisor #Cyan
    participant ActivityStack #Cyan
    participant ApplicationThreadProxy #Silver
    participant InnerReceiver #Magenta
    participant ReceiverDispatcher #Magenta
    participant BroadcastReceiver #Magenta
    
    autonumber
    Activity -> ContextWrapper : registerReceiver()
    ContextWrapper -> ContextImpl : registerReceiver()
    ContextImpl -> LoadedApk : getReceiverDispatcher()
    LoadedApk -> ActivityManagerProxy : registerReceiver()
    ActivityManagerProxy -> ActivityManagerService : registerReceiver()
    
    Activity -> ContextWrapper : sendBroadcast()
    ContextWrapper -> ContextImpl : sendBroadcast()
    ContextImpl -> ActivityManagerService: broadcastIntent()
    ActivityManagerService -> ActivityManagerService : broadcastIntentLocked()
    ActivityManagerService -> ActivityManagerService : collectReceiverComponents()
    ActivityManagerService -> ActivityManagerService : scheduleBroadcastsLocked()
    ActivityManagerService -> ActivityManagerService : processNextBroadcast()
    ActivityManagerService -> ActivityManagerService : deliverToRegisteredReceiverLocked()
    ActivityManagerService -> ActivityManagerService : performReceiveLocked()
    ActivityManagerService -> ApplicationThreadProxy : scheduleRegisteredReceiver()
    ApplicationThreadProxy -> InnerReceiver : performReceive()
    InnerReceiver -> ReceiverDispatcher : performReceive()
    ReceiverDispatcher -> BroadcastReceiver : onReceive()
    
    Activity -> ContextWrapper : sendOrderedBroadcast()
    ContextWrapper -> ContextImpl : sendOrderedBroadcast()
    ContextImpl -> ActivityManagerService: broadcastIntent()
    @enduml

4. 用例图:

    @startuml
    :Main Admin: as Admin
    (Use the application) as (Use)
    
    User -> (Start)
    User --> (Use)
    
    Admin ---> (Use)
    
    note right of Admin : This is an example.
    
    note right of (Use)
    A note can also
    be on several lines
    end note
    
    note "This note is connected\nto several objects." as N2
    (Start) .. N2
    N2 .. (Use)
    @enduml

5. 状态图

    @startuml
    scale 350 width
    [*] --> NotShooting
    
    state NotShooting {
      [*] --> Idle
      Idle --> Configuring : EvConfig
      Configuring --> Idle : EvConfig
    }
    
    state Configuring {
      [*] --> NewValueSelection
      NewValueSelection --> NewValuePreview : EvNewValue
      NewValuePreview --> NewValueSelection : EvNewValueRejected
      NewValuePreview --> NewValueSelection : EvNewValueSaved
    
      state NewValuePreview {
         State1 -> State2
      }
    
    }
    @enduml

6. 组件图

案例1:

    @startuml
    
    package "Some Group" {
    HTTP - [First Component]
    [Another Component]
    }
    
    package "Other Groups" {
    FTP - [Second Component]
    
    [First Component] --> FTP
    }
    
    @enduml

案例2:

    @startuml
    
    package "组件1" {
        ["组件1.1"] - ["组件1.2"]
        ["组件1.2"] -> ["组件2.1"]
    }
    
    node "组件2" {
        ["组件2.1"] - ["组件2.2"]
        ["组件2.2"] --> [负载均衡服务器]
    }
    
    cloud {
        [负载均衡服务器] -> [逻辑服务器1]
        [负载均衡服务器] -> [逻辑服务器2]
        [负载均衡服务器] -> [逻辑服务器3]
    }
    
    database "MySql" {
        folder "This is my folder" {
            [Folder 3]
        }
    
        frame "Foo" {
            [Frame 4]
        }
    }
    
    [逻辑服务器1] --> [Folder 3]
    [逻辑服务器2] --> [Frame 4]
    [逻辑服务器3] --> [Frame 4]
    
    @enduml