---
# System prepended metadata

title: 第五章 軟體所顯示的類型

---

# 第五章 軟體所顯示的類型
CH5 本章重點：
* 本章主要討論如何設計和簡化關聯的開始,主要專注三種模型
    * ENTITY
    * VALUE OBJECT
    * SERVICE 
---
## 關聯
關聯的控制
1. 規定一個關聯方向
2. 增加一個限定條件,以便有效的減少多重關聯
3. 減少沒必要的關聯

以下有三種關聯類型
* 一對一關聯
* 一對多關聯
* 多對多關聯


## ENTITY
1. 實體(Entity)
根據系統需求分析，寫出及畫出所有的實體(Entity)，並加以說明其意義。將真實世界的人、事、物等實體，以一個方框圖來表示，如果實體必須依附其他實體而存在，則為弱實體，使用雙方v框圖表示。例如選課系統中的學生與課程兩個實體，學生的緊急聯絡人則為弱實體，因為學生轉學，則該學生的緊急連絡人。
下圖是學生選課系統中的實體：
![](https://i.imgur.com/XsLFbkG.png)

2. 屬性(Attribute)
實體擁有的特性稱為屬性(Attribute)，以橢圓形來表示屬性，當屬性具有多重值時，則以雙橢圓形來表示，屬性為主鍵，則屬性名稱底下畫一條底線區別，複合屬性(Composite attribute)則為屬性再分割，衍生屬性(Derived attribute)則以虛橢圓形來表示，例如選課系統中的學生實體擁有學號、姓名、性別、地址、年齡和電話等屬性。
可以如下所示：
![](https://i.imgur.com/RYyePru.png)
課程實體其屬性如下圖所示：
![](https://i.imgur.com/aziW5tC.png)
緊急聯絡人是弱實體，必須依附著學生實體，其主鍵若設定為學生學號，則此處不必繪出，如下圖所示：
![](https://i.imgur.com/ANI9MUz.png)

3. 實體關係(Relationship)
說明各實體之間相互關聯(relationship)的限制(constraints)，是指實體與實體之間如果有關聯，則將此關聯以菱形連結兩實體，並寫出對應的基數。例如：每一個學生可以選修許多課程，一門課程可以被許多學生所選；每位學生皆有一位緊急聯絡人，每位聯絡人也只對應到一位學生。
![](https://i.imgur.com/wn5U8FY.png)

當實體間的關聯為多對多時，並需將此關聯改為一個實體，如下圖所示：
![](https://i.imgur.com/8wBeqPW.png)



## VALUE OBJECT
與 Entity 相反，當一個物件沒有概念上的標識 (conceptual identity)，而你只關心它的屬性時，這個物件就可以建立成 Value Object。所以值物件可以是 3, 1.5, "1234", Date(2019-10-1)、姓名、貨幣、地址，甚至是更複雜的物件等等。不過在實作上，我們會會特別指稱那些被包成物件的稱作 Value Object。
Value Object 的屬性都是為了要描述某一個事物的特徵。
Value Object 的幾項特徵，分別有描述性、不變性、概念整體性、替換性。

1. 它度量或描述了領域中的某項概念
一間房子有戶籍地址作為標示，所以在系統中你把它當作一個 Entity，但房子擁有屋齡、顏色，這些東西並不是實際的東西，而是對房子本身的度量。屋齡描述了這間房子建成後到現在的時間，而顏色是對於他外觀的描述。

2. 不變性 (Immutability)
一個 Value Object 在創建後就不能再改變了，不過作為某個物件上的描述性屬性，他可以被替換掉。繼續用房子做例子，一間房子作為 Entity，他的屬性「顏色」這個 Value Object 可以被替換掉，如從「藍色的」房子變成「紅色的」房子，但你不會說「藍色」變成了「紅色」。
實作上，我們會用 house.color = new Color('Red') 來代替 house.color.set('Red') 

3. 將相關屬性組成一個「概念整體 (Conceptual Whole)」
這就像前面提到的金錢的例子，你必須要將相關的概念整合起來，才能完整且正確地描述一件事情。

想想看，當你今天要去銀行換匯時，你想拿 300 台幣換 10 美金。這時候你有可能遇到：

    行員拿一支簽字筆在你的台幣上寫「變成 10 美金」
    行員會收下你的 300 台幣，然後直接拿出 10 美金替換給你。
    
當你有如下的設計：

class Product {
  protected name;
  protected amount;
  protected currency;
}

應該將相關的概念 amount 與 currency 合成一個 Value Object 如下：

class Product {
  protected name
  protected Money money
}
class Money {
  protected amount;
  protected currency;
}

4. 當度量與描述改變時，可以用另一個 Value Object 替換
Value Object 的可替代性前面已經稍微提到。為了顧及不變性與概念整體性，當 Value Object 被改變時，我們會重新賦值給它。
假如說要修改商品的金額從100元變成200元，程式碼會像這樣：

        class Product {
          protected name;
          protected Money money;

          __construct()(name, money) {
            this.name = name;
            this.money = money;
          }
          function changePrice(Money money){
            this.money = money;
          }
        }
        const p = new Product('A', new Money(100, 'TWD'));
        p.changePrice(new Money(200, 'TWD'));
        
## SERVICE
serviec是作為介面的一種操作,在模型中是獨立,不向entity跟 value object 具有封裝的狀態
主要強調的是與其他物件的關西,通常是一個行為的命名
1. application service(應用)
某種功能的入口,假如要寫一個api用來註冊賬號會使用AccountApplicationService來處理註冊的服務

2. infrastructure service（基礎設施）
實現不依賴於業務(domain)的功能。簡單的例子來講，比如紀錄log，發送信件,獨立的服務

## model driven design

1. 不要和實作範式對抗
2. 把通用語言作為依靠的基礎
3. 不要一昧依賴UML
4. 保持懷疑態度




