---
# System prepended metadata

title: Design Pattern
tags: [mosh youtuber, 程式]

---

###### tags: `程式` `mosh youtuber`

# Design Pattern
![](https://i.imgur.com/x5Di0Sh.png)
分成三大類，23種design pattern
1. Creational：創造object的不同方法
2. Structural：the relationships of object
3. Behavioural：the interaction and communication between these object.

## Coupling
- how many class is dependent on another class.
### 例如
#### Before
![](https://i.imgur.com/Lf0v3qj.png)
#### After
![](https://i.imgur.com/gZAYbA6.png)
![](https://i.imgur.com/JZLJQTs.png)
- 你有兩個class，Main and User，而Main class裡面有User class，當User class改變時，Main class中宣告的user class也要改變，造成Main class會需要==重新編譯==。
- 這樣造成： 如果User class被很多其他class所使用時，當User class改變時，其他所有class也會被跟著==重新編譯==

### 解法
- 可以用interface解決此問題

## interface
- a contract that specifies the capabilities that a vlass should provide

### 例子 
### Before
#### interface
![](https://i.imgur.com/gs3Dm4R.png)
#### Calculator2019
![](https://i.imgur.com/GyD8xuU.png)
#### Calculator2020
![](https://i.imgur.com/nhFQBUz.png)
#### Main class
![](https://i.imgur.com/SUBJfTt.png)

- 以計算機為例子，==計算機每年功能會增加或改變==，所以我們不希望計算機會和其他class coupling在一起，所以用interface來使用計算機。

### After
#### Calculator2019
![](https://i.imgur.com/KhSbAbF.png)
#### Main class
![](https://i.imgur.com/BKVU0WJ.png)

- 當你用interface的方式來使用計算機時，當calculator2019改變時，==不會影響Main class==造成他重新編譯。
:::info
在上述的例子中，因為public static TaxCalculator2019是宣告在Main class裡，所以實際上Main class也會重新編譯，但實際上使用interface，會使用==dependency injection framework==來實現，而免於這樣的問題。
:::

## Encapsulation
- 一種防止外界呼叫端，去存取物件內部實作細節的手段
### 例子
#### Account class
![](https://i.imgur.com/qmZl5Yr.png)
#### Main class
![](https://i.imgur.com/DF3h1IQ.png)
- 你希望Account class中的balance，不要直接被外部給存取或修改，因為可能有些情況下，對方會輸入不可預期的改動，導致整個系統出錯。
    - 以這為例，==balance(存款)不可能為負值==，所以在setBalance中，你會設下一個方法，當外部修改Balance為負值是不被允許的。


## Abstraction
- we should reduce complexity by hiding unnecessary details in our class
### 例子
#### Before
#### Main Serivce class
![](https://i.imgur.com/ld51VSn.png)
![](https://i.imgur.com/kycnRku.png)
![](https://i.imgur.com/O9jKoOj.png)
#### Main class
![](https://i.imgur.com/q6EvRYR.png)
- 你想要做MailService，來完成傳送email的功能，但是傳送email需要許多的步驟，連接到service、disconnect service、authenticate使用者，但對於使用MailService的人來說，他只需要看到sendEmail這個方法就好，他不需要了解MailService在完成email傳送時，需要要的所有細節。
#### After 

#### MailService class
![](https://i.imgur.com/wPfxeMY.png)

#### Main class
![](https://i.imgur.com/ivmFC5g.png)

- 你可以在MailService上把不需要給外部的function隱藏起來，讓這個MainService class變得更加的好用。

## inheritance

- 目的是為了reuse程式碼
### 例子
#### Main class
![](https://i.imgur.com/bpBDnTt.png)
#### UIControl class
![](https://i.imgur.com/NPkxCdc.png)
#### TextBox class
![](https://i.imgur.com/nGZzSOz.png)
- 我們在TectBox中並沒有實作enable function，而是繼承了UIControl來減少重複reuse code.

## Polymorphism
- ability of an object ot take on many forms

### 例子
#### UIControl class
![](https://i.imgur.com/n64Y9rV.png)
#### TextBox class
![](https://i.imgur.com/fa7oAgg.png)
#### CheckBox class
![](https://i.imgur.com/aMXLLL5.png)
#### 第一種使用法
![](https://i.imgur.com/80W7EpT.png)
#### 第二種使用法
![](https://i.imgur.com/cSte4zj.png)

- 我們想要讓繼承的class都draw方法，但是實際上的實作方式，每個繼承的class不同，所以我們使用abstract來宣告這個方法，讓每個subclass自己實作，但這加上abstract後，不能直接實例化UIControl class，我們必須==讓它接收實例化的小孩==，來使用它。
- 我們可以看到第一種和第二種方法上，我們用相同的function，但是用subclass來實例化UIControl class，來使用draw方法，也就是多型的概念，==單一的object(UIControl class)，可以變成各式各樣繼承它的subclass==。

## UML(Unified Modeling Language)
- 把class和function之間的關係給視覺化的語言。
### inheritance
![](https://i.imgur.com/cBVpE3q.png)
### composition
![](https://i.imgur.com/9NDSTfN.png)
### dependency
![](https://i.imgur.com/mMqwegP.png)
![](https://i.imgur.com/zpanj5t.png)


# Memento Pattern
- implementing undo mechanisms
- 還原上一步的動作

## 例子
### UML
- 我們想實現undo功能，可能會使用prevContent來存前一個狀態。
- 但是這樣每次要存一個新的content，如title我們就得再用新的preTitle去存它，這樣太麻煩了，所以使用EditorState來統一做宣告，這樣一來就不會有很多的preXXX來污染我們的命名空間
![](https://i.imgur.com/LbABDcR.png)
- 可是Editor裡面有List和content違反Single Responsibility Principal，一個Editor可能會因為兩種原因而改變
    - 因為修改content型別，而改變了Editor
    - 因為修改了prevState的存取方式，而要修改Editor。
![](https://i.imgur.com/RAqRxeC.png)
- 所以我們把prevState移出去Editor class，讓history class來管理prevState。
![](https://i.imgur.com/rJdhCZn.png)
### 實作
#### EditorState class
![](https://i.imgur.com/7VmXu9v.png)
#### Editor class
![](https://i.imgur.com/HeJW7Ud.png)
#### history class
![](https://i.imgur.com/1kVBrRI.png)

### Main class
![](https://i.imgur.com/nLh2nEL.png)
- 從Main class可以看到，我們使用Editor後，用一個通用的history來管理undo功能。
- 並且可以看出history的管理方式的改變，並不會影響到editor的任何功能。


# State Pattern
- 若是你有太多的if判斷在相同地點，且未來這if判斷會越來愈多
    -例如： ![](https://i.imgur.com/Qyd6QQB.png)
    - 你就想說這個可以用state Pattern去替換掉
## 例子 Canvas
- 在使用Phtoshop時，Canvas上的Mouse會因為你選取不同的TOOLSelection而改變，
![](https://i.imgur.com/DtLtOQk.png)

### UML
- 用Polymorphism去實現一個Tool來實作出State Pattern
![](https://i.imgur.com/V2uaFN1.png)

### 實作
#### Tool class
![](https://i.imgur.com/eihQJH7.png)
#### BrushTool
![](https://i.imgur.com/hnMlnuN.png)
#### SelectionTool class
![](https://i.imgur.com/QvbmQue.png)
#### Canvas class
![](https://i.imgur.com/D7G2TcG.png)
![](https://i.imgur.com/I1rhYXd.png)
- 在這裡你可以看到我們修改了mouseDown和mouseUp中的if判斷式，而是把這些功能寫在新創建的class中，把實作==委派==給這些Tool。
#### Main class
![](https://i.imgur.com/iJoi78h.png)
 - 在Main中，而你了解到你要切換不同的功能時，只要傳入不同的工具就好。
- 也就是說，你用多型來使用state pattern
:::info
這樣的好處是，你實現了OPEN-CLOSE Principal。
![](https://i.imgur.com/ALiPSzF.png)
當你增新的功能時，完全不用改動之前的程式碼，只要創建新的class後就好。
:::

# 參考資料
- https://www.youtube.com/watch?v=NU_1StN5Tkk&t=444s&ab_channel=ProgrammingwithMosh


# Factory Pattern
- 有三種
    - simple factory
    - factory method
    - abstract factory

## simple factory
![](https://i.imgur.com/Bhi4qWL.png)
- 使用一個工廠去生產出商品，但是當商品種類增加時，工廠內的程式碼需要修改，違反opc原則。
## factory mehtod
:::info
The factory method pattern define an interface for creating an object,but let's the subclass decide which class to instantiate. 
Factory method defer instantiation to subclass
:::
![](https://i.imgur.com/qFlvAHR.png)
- 你可以把工廠抽象出來，變成一個interface，之後若有新的商品出現，則你只需要也增新工廠的總類就好了。
## abstract factory
![](https://i.imgur.com/4vqWJuA.png)
- 一個工廠就只負責一種商品的生廠，但是當商品種類又分得更細時，會產生過多的工廠，所以我們讓工廠生產多項產品。

## 參考資料
- https://skyyen999.gitbooks.io/-study-design-pattern-in-java/content/simpleFactory.html
- https://blog.amowu.com/factory-pattern/