Notations

資料庫設計與 UML 標記法,包含 ER Diagram、類別圖符號與 Mermaid 語法範例。

ER Diagram to Relation

ER to Relation Model
ER to Relation Model 2

Entity Relation

Entity Relation

UML Notation

Mermaid Syntax

Inheritance

符號:<|--

  classDiagram
    classA <|-- classB

Composition

符號:*--

  classDiagram
    classC *-- classD
class Engine {
    public void start() {
        System.out.println("Engine started");
    }
}

class Car {
    private Engine engine;

    public Car() {
        this.engine = new Engine();  // Composition
    }

    public void startCar() {
        engine.start();
    }
}

Aggregation

符號:o--

  classDiagram
    classE o-- classF
// 部分:Player
type Player struct {
    Name string
}

// 整體:Team
type Team struct {
    Players []*Player  // Aggregation: Team has references to Player
}

func main() {
    player1 := &Player{Name: "Alice"}
    player2 := &Player{Name: "Bob"}

    team := Team{Players: []*Player{player1, player2}}

    // Team 銷毀後,Player 仍可獨立存在
    team = Team{}

    fmt.Println(player1.Name)  // Alice
    fmt.Println(player2.Name)  // Bob
}

Association

符號:-->(單向)、--(雙向)

  classDiagram
    classG <-- classH
  classDiagram
    classI -- classJ

Dependency

符號:..>

  classDiagram
    classK <.. classL
class Engine {
    public void start() {
        System.out.println("Engine started");
    }
}

class Car {
    private Engine engine;

    // Constructor Injection (Dependency)
    public Car(Engine engine) {
        this.engine = engine;
    }
}

Realization

符號:..|>(實作介面)、..(虛線連結)

  classDiagram
    classM <|.. classN
  classDiagram
    classO .. classP

Aggregation / Composition / Dependency

比較項目Aggregation(聚合)Composition(組合)Dependency(依賴)
耦合性弱耦合,部分和整體可以分開存在強耦合,部分和整體緊密相連,不能單獨存在弱耦合,類只使用依賴的對象,無需控制其生命週期
依賴物件的控制權部分可以被其他對象共享,整體不完全控制部分的生命週期整體完全控制部分的生命週期,部分依賴整體的存在依賴物件的建立與銷毀不由依賴它的類負責,通常由外部管理
生命週期關聯性部分與整體的生命週期獨立,整體被銷毀時,部分可以繼續存在部分的生命週期與整體相關,整體被銷毀時,部分也會被銷毀依賴物件與類的生命週期無關,類僅在需要時使用依賴物件
關係類型整體與部分的關係,但部分可以與其他整體共享整體與部分的關係,部分嚴格屬於整體,不可共享使用關係,類僅在特定時刻需要依賴物件,無擁有關係

Go 實作範例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
type Engine struct {
    power int
}

func (e *Engine) Start() {
    fmt.Println("引擎啟動,功率:", e.power)
}

type Car struct {
    Engine  // Composition
    brand string
}

func NewCar(brand string, power int) *Car {
    return &Car{
        Engine: Engine{power: power}, // Car 銷毀,Engine一同銷毀
        brand:  brand,
    }
}

func (c *Car) Drive() {
    fmt.Printf("%s 車開始行駛\n", c.brand)
    c.Start()
}

func main() {
    myCar := NewCar("Toyota", 150)
    myCar.Drive()
}
type Driver struct {
    name string
}

func (d *Driver) Drive(car *Car) {
    fmt.Printf("%s 正在駕駛 ", d.name)
    car.Drive()
}

func main() {
    myCar := NewCar("Toyota", 150)
    driver := &Driver{name: "Alice"}
    driver.Drive(myCar)
}
type Garage struct {
    cars []*Car  // Aggregation
}

func (g *Garage) AddCar(car *Car) {
    g.cars = append(g.cars, car)
}

func (g *Garage) RemoveCar(car *Car) {
    for i, c := range g.cars {
        if c == car {
            g.cars = append(g.cars[:i], g.cars[i+1:]...)
            break
        }
    }
}

func main() {
    myCar := NewCar("Toyota", 150)
    garage := &Garage{}
    garage.AddCar(myCar)
    garage.AddCar(NewCar("Honda", 120))

    fmt.Println("車庫中的車輛數量:", len(garage.cars))

    garage.RemoveCar(myCar)
    fmt.Println("移除一輛車後,車庫中的車輛數量:", len(garage.cars))
}

關係類型總結

關係類型實現方式生命週期特點
CompositionCar struct 嵌入 Engine structEngine 的生命週期與 Car 完全綁定。Car 創建時 Engine 創建,Car 銷毀時 Engine 銷毀Car 可直接使用 Engine 的方法,如 c.Start()
DependencyDriver 的 Drive() 接受 *Car 參數Driver 和 Car 的生命週期獨立。Driver 只是在需要時使用 CarDriver 不擁有 Car,只是暫時使用它
AggregationGarage struct 包含 []*Car sliceGarage 和 Car 的生命週期獨立。Car 可存在於 Garage 之外Garage 可添加或移除 Car,但不負責 Car 的創建或銷毀