2022/08/26

Mermaid - State Diagram

stateDiagram-v2
    [*] --> Still
    Still --> [*]

    Still --> Moving
    Moving --> Still
    Moving --> Crash
    Crash --> [*]

舊版是 stateDiagram,節點看起來比較小,故應該使用 stateDiagram-v2

States

有三種寫法

stateDiagram-v2
    s1
    state "s2 state description" as s2
    s3 : s3 state description

render 結果

Transition

stateDiagram-v2
    s1 --> s2
    s2 --> s3: A transition

render 結果

Start & End

stateDiagram-v2
    [*] --> s1
    s1 --> [*]

render 結果

Composite State

stateDiagram-v2
    [*] --> First
    First --> Third

    state First {
        [*] --> Second

        state Second {
            [*] --> second
            second --> [*]
        }
    }
    state Third {
        [*] --> third
        third --> [*]
    }

render 結果

Choice

類似流程圖,可判斷選擇路徑

stateDiagram-v2
    state if_state <<choice>>
    [*] --> IsPositive
    IsPositive --> if_state
    if_state --> False: if n < 0
    if_state --> True : if n >= 0

Fork

stateDiagram-v2
    state fork_state <<fork>>
      [*] --> fork_state
      fork_state --> State2
      fork_state --> State3

      state join_state <<join>>
      State2 --> join_state
      State3 --> join_state
      join_state --> State4
      State4 --> [*]

render

Note

在 node 的 right of 或 left of 放上 note

stateDiagram-v2
        State1: The state with a note
        note right of State1
            Important information! You can write
            notes.
        end note
        State1 --> State2
        note left of State2 : This is the note to the left.

render

Concurrency

可用 -- 表示同時發生的 state

stateDiagram-v2
    [*] --> Active

    state Active {
        [*] --> NumLockOff
        NumLockOff --> NumLockOn : EvNumLockPressed
        NumLockOn --> NumLockOff : EvNumLockPressed
        --
        [*] --> CapsLockOff
        CapsLockOff --> CapsLockOn : EvCapsLockPressed
        CapsLockOn --> CapsLockOff : EvCapsLockPressed
        --
        [*] --> ScrollLockOff
        ScrollLockOff --> ScrollLockOn : EvScrollLockPressed
        ScrollLockOn --> ScrollLockOff : EvScrollLockPressed
    }

render

Direction

將圖表方向由上下改為 LR, MarkText 不支援 direction

stateDiagram
    direction LR
    [*] --> A
    A --> B
    B --> C
    state B {
      direction LR
      a --> b
    }
    B --> D

2022/08/22

Mermaid - Sequence Diagram

mermaid 支援 UML 中的 sequence diagram

Syntax

Participants 明確標示參與的角色,以方框表示

sequenceDiagram
    participant Alice
    participant John
    Alice->>John: Hello John, how are you?
    John-->>Alice: Great!
    Alice->>John: See you later!

render

participant 可替換為 actor,會改成用 UML 代表人物的 actor 表示。(MarkText 不支援 actor 語法)

sequenceDiagram
    actor Alice
    actor Bob
    Alice->>Bob: Hi Bob
    Bob->>Alice: Hi Alice

alias 是 actor 的縮寫 ex: participant A as Alice

sequenceDiagram
    participant A as Alice
    participant J as John
    A->>J: Hello John, how are you?
    J->>A: Great!

render

Message

可用實線或虛線,語法為

[Actor][Arrow][Actor]:Message text

Arrow 的部分有六種

Type Description
-> Solid line without arrow
--> Dotted line without arrow
->> Solid line with arrowhead
-->> Dotted line with arrowhead
-x Solid line with a cross at the end
--x Dotted line with a cross at the end.
-) Solid line with an open arrow at the end (async)
--) Dotted line with a open arrow at the end (async)
sequenceDiagram
    participant A as Alice
    participant J as John
    A->J: M1
    A-->J: M2
    A->>J: M3
    A-->>J: M4
    A-xJ: M5
    A--xJ: M6
    %%A-)J: M7
    %%A--)J: M8

render

Activations

可 activate/deactivate actor,在 Sequence Diagram 裡面代表該 actor 花時間處理一些工作,語法為 activate/deactivate,也可在 message arrow 後面使用 + -。

activatation 可在同一個 actor 裡面 stacked

sequenceDiagram
    Alice->>John: Hello John, how are you?
    activate John
    John-->>Alice: Great!
    deactivate John

    Alice->>+John: Hello John, how are you?
    John-->>-Alice: Great!

    Alice->>+John: Hello John, how are you?
    Alice->>+John: John, can you hear me?
    John-->>-Alice: Hi Alice, I can hear you!
    John-->>-Alice: I feel great!

render

Note

可在 sequence diagram 加上 note,

Note [ right of | left of | over ] [Actor]: Text in note content

sequenceDiagram
    participant John
    Note right of John: Text of John
    Alice->John: Hello John, how are you?
    Note over Alice,John: A Note Over Alice, John

render

Loop

語法為

loop Loop text
... statements ...
end
sequenceDiagram
    Alice->John: Hello John, how are you?
    loop Every minute
        John-->Alice: Great!
    end

render

Alt

代表 alternative path,以下為語法,可不寫 else

alt Describing text
... statements ...
else
... statements ...
end
sequenceDiagram
    Alice->>Bob: Hello Bob, how are you?
    alt is sick
        Bob->>Alice: Not so good :(
    else is well
        Bob->>Alice: Feeling fresh like a daisy
    end
    opt Extra response
        Bob->>Alice: Thanks for asking
    end

render

Parallel

同時發生的動作

par [Action 1]
... statements ...
and [Action 2]
... statements ...
and [Action N]
... statements ...
end

example

sequenceDiagram
    par Alice to Bob
        Alice->>Bob: Hello guys!
    and Alice to John
        Alice->>John: Hello guys!
    end
    Bob-->>Alice: Hi Alice!
    John-->>Alice: Hi Alice!

render

可以 nest parallel blocks

sequenceDiagram
    %% 可 nest parallel blocks
    par Alice to Bob
        Alice->>Bob: Go help John
    and Alice to John
        Alice->>John: I want this done today
        par John to Charlie
            John->>Charlie: Can we do this today?
        and John to Diana
            John->>Diana: Can you help us today?
        end
    end

render

hightlight 背景

以 rgb 或 rgba 定義顏色

rect rgb(0, 255, 0)
... content ...
end

rect rgba(0, 0, 255, .1)
... content ...
end

example

sequenceDiagram
    participant Alice
    participant John

    rect rgb(191, 223, 255)
    note right of Alice: Alice calls John.
    Alice->>+John: Hello John, how are you?
    rect rgb(200, 150, 255)
    Alice->>+John: John, can you hear me?
    John-->>-Alice: Hi Alice, I can hear you!
    end
    John-->>-Alice: I feel great!
    end
    Alice ->>+ John: Did you want to go to the game tonight?
    John -->>- Alice: Yeah! See you there.

render

Sequence Number

autonumber

sequenceDiagram
    autonumber
    Alice->>John: Hello John, how are you?
    loop Healthcheck
        John->>John: Fight against hypochondria
    end
    Note right of John: Rational thoughts!
    John-->>Alice: Great!
    John->>Bob: How about you?
    Bob-->>John: Jolly good!

render

Actor Menu

語法,在 MarkText 不能使用

link <actor>: <link-label> @ <link-url>
sequenceDiagram
    participant Alice
    participant John
    link Alice: Dashboard @ https://dashboard.contoso.com/alice
    link Alice: Wiki @ https://wiki.contoso.com/alice
    link John: Dashboard @ https://dashboard.contoso.com/john
    link John: Wiki @ https://wiki.contoso.com/john
    Alice->>John: Hello John, how are you?
    John-->>Alice: Great!
    Alice->>John: See you later!

render

2022/08/15

Mermaid - Gantt & Pie Chart

Mermaid - Gantt & Pie Chart

Gantt

這是 Gantt Chart 的範例,在圖表中,在今天畫上一條紅色直線。

gantt
    title A Gantt Diagram
    dateFormat  YYYY-MM-DD

    section Section
    A task           :a1, 2022-02-01, 30d
    Another task     :after a1  , 20d

    section Another
    Task in sec      :2022-02-12  , 12d
    another task     : 24d

render

Syntax

以下是 gantt chart 的相關語法

gantt
    dateFormat  YYYY-MM-DD
    title       Adding GANTT diagram functionality to mermaid
    excludes    weekends
    %% (`excludes` accepts specific dates in YYYY-MM-DD format, days of the week ("sunday") or "weekends", but not the word "weekdays".)

    section A section
    Completed task            :done,    des1, 2014-01-06,2014-01-08
    Active task               :active,  des2, 2014-01-09, 3d
    Future task               :         des3, after des2, 5d
    Future task2              :         des4, after des3, 5d

    section Critical tasks
    Completed task in the critical line :crit, done, 2014-01-06,24h
    Implement parser and jison          :crit, done, after des1, 2d
    Create tests for parser             :crit, active, 3d
    Future task in critical line        :crit, 5d
    Create tests for renderer           :2d
    Add to mermaid                      :1d
    Functionality added                 :milestone, 2014-01-25, 0d

    section Documentation
    Describe gantt syntax               :active, a1, after des1, 3d
    Add gantt diagram to demo page      :after a1  , 20h
    Add another diagram to demo page    :doc1, after a1  , 48h

    section Last section
    Describe gantt syntax               :after doc1, 3d
    Add gantt diagram to demo page      :20h
    Add another diagram to demo page    :48h

render

可以用 space 區隔多個 dependencies

gantt
    apple :a, 2017-07-20, 1w
    banana :crit, b, 2017-07-23, 1d
    cherry :active, c, after b a, 1d

render

section 用來區分專案不同的工作部分,section 後面是該 section 的名稱,是一定要填寫的

Milestones

milestone 是一種不同類別的 task,代表特殊的時間點。milestone 的位置是initial date + duration/2

gantt 
dateFormat HH:mm
axisFormat %H:%M
Initial milestone : milestone, m1, 17:49,2min
taska2 : 10min
taska3 : 5min 
Final milestone : milestone, m2, 18:14, 2min

render

Date Format

dateFormat YYYY-MM-DD

可使用以下這些日期格式

Input       Example             Description:
YYYY        2014                4 digit year
YY          14                  2 digit year
Q           1..4                Quarter of year. Sets month to first month in quarter.
M MM        1..12               Month number
MMM MMMM    January..Dec        Month name in locale set by moment.locale()
D DD        1..31               Day of month
Do          1st..31st           Day of month with ordinal
DDD DDDD    1..365              Day of year
X           1410715640.579      Unix timestamp
x           1410715640579       Unix ms timestamp
H HH        0..23               24 hour time
h hh        1..12               12 hour time used with a A.
a A         am pm               Post or ante meridiem
m mm        0..59               Minutes
s ss        0..59               Seconds
S           0..9                Tenths of a second
SS          0..99               Hundreds of a second
SSS         0..999              Thousandths of a second
Z ZZ        +12:00              Offset from UTC as +-HH:mm, +-HHmm, or Z

橫軸的日期格式

axisFormat  %Y-%m-%d

可使用以下日期格式

%a - abbreviated weekday name.
%A - full weekday name.
%b - abbreviated month name.
%B - full month name.
%c - date and time, as "%a %b %e %H:%M:%S %Y".
%d - zero-padded day of the month as a decimal number [01,31].
%e - space-padded day of the month as a decimal number [ 1,31]; equivalent to %_d.
%H - hour (24-hour clock) as a decimal number [00,23].
%I - hour (12-hour clock) as a decimal number [01,12].
%j - day of the year as a decimal number [001,366].
%m - month as a decimal number [01,12].
%M - minute as a decimal number [00,59].
%L - milliseconds as a decimal number [000, 999].
%p - either AM or PM.
%S - second as a decimal number [00,61].
%U - week number of the year (Sunday as the first day of the week) as a decimal number [00,53].
%w - weekday as a decimal number [0(Sunday),6].
%W - week number of the year (Monday as the first day of the week) as a decimal number [00,53].
%x - date, as "%m/%d/%Y".
%X - time, as "%H:%M:%S".
%y - year without century as a decimal number [00,99].
%Y - year with century as a decimal number.
%Z - time zone offset, such as "-0700".
%% - a literal "%" character.

Comments

%% 開頭的那一行,都是註解

## Pie Chart

語法,只要直接填寫數值,會自動計算為 Pie Chart 裡面的比例

[pie] [title] [titlevalue] (OPTIONAL)
"[datakey1]" : [dataValue1]
"[datakey2]" : [dataValue2]
"[datakey3]" : [dataValue3]

Example

pie
    title Key elements in Product X
    "Calcium" : 42.96
    "Potassium" : 50.05
    "Magnesium" : 10.01
    "Iron" :  5

render

2022/08/08

Mermaid - Flowchart

Mermaid 是用 text 與 code 撰寫 diagrams 的語法,能夠用在 markdown 的 codeblock 裡面,目前支援的語法有 flowchart, sequence diagram, class diagram, state diagram, entity relationship diagram, gantt chart, user journey diagram。

Mermaid Live Editor 是線上編輯的工具,也可以在 Markdown 工具裡面試試看以沒有支援 mermaid,可在 code block 的 lang 填上 mermaid。

flowchart LR
    A-->B

實際上 render flowchart 會是這樣

Flowchart

Orientation

第一行 flowchart 後面要指定方向

  • TB - top to bottom
  • TD - top-down/ same as top to bottom
  • BT - bottom to top
  • RL - right to left
  • LR - left to right

Node

節點的前面是 id,後面是節點格式及文字

flowchat LR
id1(圓角節點)
id2([stadium-shaped node])
id3[[subroutine shaped node]]
id4[(cylindrical shaped Database)]
id5((circle))
id6{rhombus}
id7{{hexagon}}
id8[/parallelogram/]
id9[\parallelogram alt\]
id10[/trapezoid\]
id11[\trapezoid alt/]

實際上 render 會是這樣

flowchart LR
A --> B
C --- D
E --text on link---F
G --text on link2-->H
I ---|text on link|J
K -->|text on link|L
M -.-> N
O -. dotted link with text .-> P
Q ==> R
S == thick link with text ==> T
U -- chain --> V -- chain --> W
a --> b & c --> d
e & f--> g & h
i --o j
j --x k

實際上 render 會是這樣

特殊字元

" 把文字填在裡面,另外可用 #quote; 代表 :,支援 HTML character names

flowchart LR
id1["This is the (text) in the box"]
A["A double quote:#quot;"] -->B["A dec char:#9829;"]

可倍 render 為

flowchart LR
id1["This is the (text) in the box"]
A["A double quote:#quot;"] -->B["A dec char:#9829;"]

subgraph

語法為

subgraph title
    graph definition
end

subgraph subgraphid [title]
    graph definition
end

範例

flowchart TB
    c1-->a2
    d1-->a2
    subgraph one
    a1-->a2
    end

    subgraph two
    b1-->b2
    end

    subgraph sid1 [three]
    c1-->c2
    end

render 結果

flowcharts

可在 flowchart 之間加上 edges

flowchart TB
    c1-->a2
    subgraph one
    a1-->a2
    end
    subgraph two
    b1-->b2
    end
    subgraph three
    c1-->c2
    end

    one --> two
    three --> two
    two --> c2

render

subgraph 之間加上方向(direction 語法在 MarkText 不支援)

flowchart LR
  subgraph TOP
    direction TB
    subgraph B1
        direction RL
        i1 -->f1
    end
    subgraph B2
        direction BT
        i2 -->f2
    end
  end
  A --> TOP --> B
  B1 --> B2

Interaction

當 js 為 securityLevel='strict' 這個功能會被 disable,securityLevel='loose' 則會 enabled

click nodeId callback
click nodeId call callback()

可在 js 增加 callback() function 讓 mermaid node 使用

<script>
  var callback = function(){
      alert('A callback was triggered');
  }
</script>

Styling a node

可設定不同的 border,或 background顏色

flowchart LR
    id1(Start)-->id2(Stop)
    style id1 fill:#f9f,stroke:#333,stroke-width:4px
    style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5

render

用 classDef 可更方便地定義新的 style class

classDef className fill:#f9f,stroke:#333,stroke-width:4px;
class nodeId1 className;
class nodeId1,nodeId2 className;
%% 用 ::: 可快速指定 node 的 style class
A:::className
flowchart LR
    A:::someclass --> B
    classDef someclass fill:#f96;

render

References

mermaid github

網頁流程圖函式庫 mermaid.js

2022/08/01

物件導向設計 SOLID 原則

SOLID 是 Robert C. Martin 提出物件導向系統的五個設計原則,套用這些原則開發的系統,能夠更容易被維護與擴充功能。

S: Single Responsibility Principle 單一功能原則

O: Open-Close Principle 開放封閉原則

L: Liskov’s Substitution Principle 里氏替換原則

I: The Interface Segregation Principle 介面隔離原則

D: The Dependency Inversion Principle 依賴反轉原則

有些文件提供了六個設計原則,另外一個是

L: Law of Demeter 迪米特原则

單一功能原則

每個物件,不管是類別、函數,都只負責一項功能。

每個函數都只能有一種功能,這邊比較直覺,但類別的部分比較難判斷,什麼時候必須把有相近功能的函數放在同一個類別裡面。

可先利用使用/呼叫這個類別的其他類別的角色來判斷,例如網頁 rest Command,資料庫存取介面,然後在因應不同的 rest url 或是不同的 table 區分類別。

開放封閉原則

對功能擴充開放,對修改封閉。

要增加新的程式碼,擴充原有系統的新功能,而不是修改既有功能的程式碼。

已經正常運作的東西沒有壞掉,就不要任意修改的意思。這個方法最常用在維護舊系統程式碼的狀況,有時會遇到要修改其他人寫的程式,或雖然是自己寫的程式,但已經很久沒有看過,已經忘記當時的實作細節的時候,就要用擴充的方式去修改舊系統的程式。

開放封閉原則在大部分的情況下是正確的,但有時候一些舊系統的程式碼,已經很確定有明顯的錯誤或設計問題時,還是必須要狠心用力去修改,如果還是以擴充的方式去做,只會讓專案更亂。

里氏替換原則

程式中的物件可以在不改變程式正確性的前提下被它的子類別所替換的。

實作了 Interface 或是繼承了某個 class,在其他程式中,如果出現該 Interface 或是父類別時,都可以用 sub-class 取代。

如果類別繼承錯誤,父類別通過的測試,子類別未必可以通過。

介面隔離原則

針對不同的使用端,開放不同的使用介面。

類別之間,透過最小的介面互相溝通。

如果只使用一個介面,可能會造成 Fat Interface,產生很多多餘的程式碼,不容易維護。

依賴反轉原則

當 A 模組在內部使用 B 模組的情況下,我們稱 A 為高階模組,B 為低階模組。高階模組不應該依賴於低階模組,兩者都該依賴抽象介面。

透過介面,讓各類別的實作分開獨立,降低類別之間的耦合度。

迪米特原则

也被稱為最小知識原則

一個物件應該對其他物件保持最小的了解,也就是低耦合,高內聚

類別之間的耦合度越高,當一個類別改變時,對另一個類別的影響越多。

總結

S: 單一類別單一功能 O: 開放擴充,封閉修改 L: 父類別可用子類別替換 I: 類別之間以最小介面互相溝通 D: 利用介面抽象化

L(LoD): 類別之間低耦合

References

SOLID (物件導向設計) - 維基百科,自由的百科全書

09. 物件導向設計原則—SOLID - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天

物件導向程式設計五大原則:SOLID-软件开发平台及语言笔记大全(超详细)

使人瘋狂的 SOLID 原則

超易懂!原來SOLID原則要這麼理解 - 每日頭條

設計模式六大原則 - 每日頭條