# 物件導向 - 鄭永斌
## 2.
- 會按照繼承的順序依序執行父類的建構子,倒著執行解構子。每一個 subclass 要自行負責建構與清除自己特異化的部分
- member initialization list:`Rat(int w) : Pet(w){}`,執行指定的父類建構子
- overload 多載 != polymorphism 多型
- 如果 override 一個在父類 overloaded (名字一樣,參數不一樣)的 method,沒被 override 的其他同名 method 都會不見,無法被call。(因為編譯器要你確定全都有 override)
- `(Pet) Cat.speak()`:轉型時,compiler會自動 call copy constructor,之後再 destruct 掉
## 3. Polymorphism
用 base class 的指標來處理時,可以根據 subclass 做不同的處理
e.g.
```c
for(Entity E in list) {
E->draw();
}
```
以下是說 c++
- 任何想被子類 override 的 method 都要宣告成 virtual,一旦被宣告成 virtual,在子類中都會是 virtual,但還是建議加一下比較好'
- 多型只對 pointer、reference,以及宣告成 virtual 的函式有效
- 如果一個 class 有任何一個 method 是 virtual 的,destructor 也要是 virtual
- 總之就是子類可能會自己特異化實現的用 virtual,但不要乾脆就全 virtual,因為有 overhead
- **object slicing**:pass by value 的時候,如果參數型別是基類,那傳子類進去時,子類的記憶體會被切掉,只會copy出一個基類物件
- 以前 C 沒有 OO 的時候就要 hardcode switch 來做多型,或是用 function pointer 和 function array
- **Indirect call**:間接呼叫,利用存在暫存器中的地址在執行時定址。e.g. `MOV [EBX], 123`
- **binding**:把記憶體位址綁到 call function 的地方
- ++compilation time binding++:自己寫的函式
- ++linking time binding++:C 內建的函式
- ++loading time binding++:去外界參考表找 function 的位址,而位址要等OS把DLL(dynamic linking library)載入到記憶體後再填進去

- Dynamic Binding:維護並使用 Virtual Function Table,一個 class 只會有一個,各實例共用

- abstract class:有純虛函式 pure virtual function `virtual void myFunc() = 0;`,因此不可能有這 class 的實例
## 4. Multiple Inheritance
- **Percolating Upward**:為了多型,把子類特異化的部分移到父類
- `dynamic_cast<[TYPE]> [VAR]`:試著把 `VAR` 轉成 `[TYPE]` 並回傳,不行就回傳 `NULL`
- casting up / down:轉成 父/子 類
- Percolating Upward 跟 Casting Down 都是 bad design,因為無法做到 ++跟未來擴充型別無關++,無法應付未來的擴充,需要回去改 code
- 多重繼承:子類繼承自兩個父類,兩個父類又繼承自同一個祖父類,則子類會 call 兩次祖父類的 constructor,並且會有兩個祖父類的記憶體空間

### c++
- 因為這樣重複的記憶體會有 ambiguity,所以 C++ 有提供一些解法
- 指定:`jetCar->Jet::stop()`,甚至是 `jetCar->Jet::Vehicle::run()`
- 子類 override 掉
- 但就算這樣有時還是不對,比如說祖父類的 "資料" 會有兩份
- **Diamond-shaped Inheritance**:鑽石型繼承,父類在繼承祖父類時使用 `virtual` 關鍵字,在多重繼承時就只會有一個祖父類
### java
- **Interface**:就是一個只能宣告純虛函式的 class,要繼承的話要用關鍵字 `implement`,然後子類自己填定義
- 介面的使用原則:A implement B,表示 A **can do** B
## 5. Comparison of Java and C++
- Java 如果要呼叫父類的建構子要用 `super()` 而且這只能在子類建構子的第一行 call,也不能用任何的 `this.xxx` 來當參數
- `super.func()`:可用來 call 父類被覆寫的函式
- `myClass[100]`:C++ 會建立 100 個物件呼叫 100 次建構子;Java 不會,只會建立 reference,所以不會 call 建構子,要之後自己 new 物件
- Java 的 primitive type 都是 pass by value;class type 都是 pass by reference
- Java 沒有 global variable
## 6. Code Quality
沒什麼特別的
## 7. DataBase Design and Normalization
- Normalization:只讓資料庫包含恰恰能描述的資料
- 移除重複的冗餘資料 (去除重複的column)
- 確保關連性合理
- foriegn key:連到另一個 table 的 column
- **1st Normal Form**
 
- **2nd Normal Form**
移除跟 primary key 無關聯的 column

- **3rd Normal Form**
Non-key value 不能有相關性

## 8. Data-Oriented Model
- middle-level notation:把設計系統時的心路歷程記下來,希望可以把高手的作法歸結出一個能照著做的方法論
- **ERD**:Entity-Relation Diagram,專注在data間如何link跟組織
- The Entity Relationship **Principle**:list of ***things***
- Entity type = class = 一個 table
- Entity = object
- Occurrence = instance
- Attribute = 一個欄位
- Assotioation: 動作 = 一個 Access path way (i.e. foreign key)
- 各種 programming language 的發明都是為了解決 software engineering 的問題
- 物件導向的程式就是為了避免之後要一直改
- Multiplicity:多對一、一對多、many-to-many
## 9. How to find classes and objects
- **Jacobson's Three Types**
- **Entity objects**:things in the users' real world
- ++concrete objects++:Employee, Product, Tool, etc
- ++Conceptual objects++:Corporation, strategy, membership, approval, etc
- ++Event and State objects++:Purchase, delivery, arrival, ownership, status, etc
- **Interface objects**:comminucation protocol,GUI、真實世界的SOP、既有系統的interface, etc
- **Control objects**:To carry complex methods that don't have a class they obviously belong in
- **The KRB Seven-Step Method**
1. ++Candidate Classes++:列出跟你的project有關的所有名詞(name),也許能當class
2. ++Define Classes++:決定要有哪些class,每個候選的class都需要經過下列三個檢查
1. A Real-World Identifier:"How do I tell one ... from another?" 這class的物件彼此間能不能區分(每位學生都不同)
2. A Definition:"What is a ... ?",能不能用一句話給這物件一個定義
3. Sample Attributes and Behaviors
3. ++Establish Associations++:物件的互動

4. ++Expand Many-to-Many Associations++:新增class去解掉M:M的情況
 
5. ++Attributes++:列出每個物件需要有的屬性
6. ++Normalization++:正規化,database的事情
7. ++Operations++:Behavior,物件的method
8. 根據物件的相似性建構繼承關係
## 10. Overview of UML
物件導向除了可重用、好維護外,還有一個重要的點是可以 modeling software before building it
- UML:Unified Modeling Language
## 12. UML class diagram
- composit:sub class 擁有 base class 型別的物件
### Class Diagram
- 描述系統中物件的 class,以及 class 間的**靜態**關聯
- Assotiation:class 間的連線箭頭表示,擁有者指向被擁有者,但 UML 2.x 移除的,不用箭頭
- Generalization 空心箭頭,表示繼承自

### Object Diagram
又被稱作 instance diagram,是系統的快照

method 畫底線是 class scope (static) 的

### Multiple Classification
連接線上的 Discriminator 解釋特異化的意義
(實心箭頭表示不能再被繼承下去)

### Dynamic Classification
標一個 \<<dynamic\>> 表示型別可能會互相轉換

### Aggregation and Composition
association 的一種
- Aggregation:聚集,一個沒了另一個還能存在。空白菱形
- Composition:合成,不可分割,同生同滅。實心菱形
菱形都是指向大的那邊

### Derived Association and Attribute
衍生的關聯或屬性,用 `/` 標註,實作時不須用一個欄位紀錄,從其他關連或屬性去推就好,比如說有++生日++就不用記++歲數++

### Interface and Abstract Class
用虛線
- Abstract

- Interface

### Classification and Generalization
1. 小白是狗
2. 狗是物種
但小白不是物種
雖然他們口語都是 is-a 關係,但 Generalization (繼承)有遞移性 classification 沒有遞移性
### Qualified Association
三小

### Association Class
給連線一個 class

其實就是省略一些中間 class,上圖等價下圖

### Template Class
C++ 的 template,標在右上角


### 箭頭
knows a 是只有指標,has a 是創建跟刪除物件

## 13 UML sequence diagram
- 又叫 interaction diagram,描述 objects (不是class) 間如何合作完成一件事
- sequence diagram
- collaboration diagram
### sequence diagram
- 由上到下表時間順序
- `*` 表示有 for loop

- 半個箭頭表示 asynchronous

- sequence diagram 不擅長展示有loop等的演算法,適合用來展示複雜的互動環境

(中間小圈O->是傳參數)

### collaboration diagram
- 因為 sequence diagram 很容易太長,所以 collaboration diagram 改用數字標執行順序,不寫成一條了。

### How to find methods of object
- two method
- **Maximize**:如果是要寫 library,設計物件的時候不知道別人會怎麼用,那就多寫一點method
- **Minimize**:如果是自己要完成一個軟體。那就不要寫不會用到的 method
## 11. Movie rental Example
- 一個設計是否良善要看未來維護需求是甚麼
- software entropy:愈來愈亂
### State Pattern
將一個物件的多種狀態封裝在不同的類別中,從而使狀態轉換更為靈活和可維護
跟 Strategy Pattern 看起來很像,但一個是狀態轉移,一個是行為更換。State Pattern 的行為邏輯沒有被抽出來,Strategy的有。
## 14. Design Pattern 1
有本四人幫(The gang of Four)的書能看
- **Design Pattern**:過去在實作各種各類的軟體過程中,許多人累積了寶貴的物件導向分析經驗。經過蒐集整理,這些寶貴的繼承架構,class diagram,物件互動架構等等,被蒐集成所謂的design patterns
- **KISS**:Keep It Simple and Stupid
### Composite Pattern
- 如果物件用composite 包含 base class,那就不要把特異化放在 sub class 了,直接 percolating up 放到 base class,不然還要判斷當前物件是甚麼類型才能 call 特異化的部分

### Proxy Pattern
### Singleton Pattern
- Global Variable is EVIL:不知道誰能存取它、耦合、汙染命名空間、多執行緒會有 concurrency 的問題
- Singleton:建構子是 private,物件等需要(第一次get)才建立,確保 class 只有一個 instance
### Strategy Pattern
- composition 可能比繼承好
- 假設有各種鴨子,++綠頭鴨++、++橡皮鴨++、++木雕鴨++,如果都繼承自「鴨子」,而鴨子有++叫++、++飛++等 function,那++橡皮鴨++、++木雕鴨++都需要各自override它們為空,導致代碼重用性很差。唉,總之就是物件裡面的方法再拉出來寫成另一個物件(比如說這些行為物件可能是實現一個叫做 behavior 的 interface 之類的)這樣就可以在物件間 reuse,甚至還能在 runtime 抽換掉 (如果用繼承來搞不同物件的行為的話,就沒法在 runtime 轉成另一個 sub class 了)

## 15. Design Pattern 2
### Factory Pattern
> [!Note] Design Principle
> **Close for Modifications**:要改code的時候不用到處改,那就要把核心 code 都用 interface 跟多型(Program to an interface, not an implementation)
>
> **Dependency Inversion Principle**:高層類別不該依賴於底層類別,要搞抽象就全都抽象
把 `new Subtype1()` 這類創建物件的東東移到 factory 物件裡,要創建物件的時候,傳參數(string 或 enum 之類的)進去 Factory 的 `createObject(Type)`,總之就是把 `new Subtype1()` 抽出來,這樣以後要改或擴充的話,去 factory 改就好
並且如果 subtype 有再分化下去成 subsubtype 的話,factory也搞個繼承變 subFactory,`createObject(Type)` 也弄成 abstract 搞多型,天知道為啥這樣比較好


 $\Rightarrow$ 
或是再把 Factory 也從使用它的 class 中抽出來,改在建構時傳進去,更解耦合

### Decorator Pattern
> [!Note] Design Principle
> Classes should be open for extension, but closed for modification
用有點像 composition 那樣的方式,從基底 class 一層一層包 decorator 上去,達到類似繼承的差異化

舉例來說,有不同的咖啡,以及不同的配料,要計算價錢,那就基底看要哪種咖啡,然後一層一層加不同配料上去,每個 decorator 和基底 class 都有 `getCost()` function,要用的時候從最外面一層層 call 進去



### Model View Control
> GUI 是軟體中最常面對變動的東東
- Model:the computational model
- View:負責把 data 畫出來
- Controller:負責 user event,然後跟 model 互動(本身不該有運算邏輯的部分,只負責怎麼把資料給 View)

#### Observer Pattern
Observer Pattern 定義了一種一對多的依賴關係,讓一個或多個觀察者物件監聽其所關心的主題物件。當這個主題物件發生狀態改變時,會對所有的觀察者發送通知。
