Learning design patterns with golang, node.js, python...
- design-pattern-learning
- Go
- Node.js
- Python
- TypeScript (need to learn...)
develop code base on docker, so you need to install Docker first.
- change workdir to
go
- run command
./dev
- change workdir to
nodejs
- build docker image
docker build -t design-pattern:node .
- run command
./dev
- change workdir to
python
- build docker image
docker build -t design-pattern:python .
- run command
./dev
- change workdir to
typescript
- build docker image
docker build -t design-pattern:typescript .
- run command
./dev
Abstract factory
pattern 是 Factory method 的延伸應用,既然創建 class 需要用到 factory
pattern,那麼取得 factory 是不是也可以抽象出一個 factory 來創建呢? 所以 Abstract factory
亦被稱為 工廠的工廠
,這時又會遇見 simple factory
提到 OO 的 Open-Closed Principle,這時部分 Language 可以使用 reflect 這個技巧,如果存在這個 factory 就將他給創建出來。
使用 abstract factory
建立食物烹煮工廠,讓廚師可以製作出飲料、烤物、燉煮類食物。
┌──────┐ ┌───────────────────────────────────────────┐
│ Main │┄┄┄┄⇢│ AbstractFactory │
└──────┘ ├───────────────────────────────────────────┤
┆ ├───────────────────────────────────────────┤┄┐ Dependency
┆ │+ getFactory(factoryName: String): Factory │ ┆
┆ └───────────────────────────────────────────┘ ┆
┆ ┆
┆ ┌────────────────────────┐ ┆ ┌──────────────────────────────────────┐
┆ │ Factory │ Inheritance ├┄⇢│ BBQFactory │
├┄┄┄⇢├────────────────────────┤⇽────────────────────┬─────┼──┼──────────────────────────────────────┼┄┄┬┄┄┄┄┄┄┄┄┄┄┐
┆ ├────────────────────────┤ │ ┆ │+ getFood(foodName: String): Food | ┆ ┆
┆ └────────────────────────┘ │ ┆ └──────────────────────────────────────┘ ┆ ┆
┆ │ ┆ ┆ ┆
┆ │ ┆ ┌──────────────────────────────────────┐ ┆ ┆
┆ │ ├┄⇢│ StewFactory │ ┆ ┆
┆ ├─────┼──┼──────────────────────────────────────┼┄┄┼┄┄┄┄┄┄┄┄┄┐┆
┆ │ ┆ │+ getFood(foodName: String): Food | ┆ ┆┆
┆ │ ┆ └──────────────────────────────────────┘ ┆ ┆┆
┆ │ ┆ ┆ ┆┆ Dependency
┆ │ ┆ ┌──────────────────────────────────────┐ ┆ ┆┆
┆ │ └┄⇢│ DrinkFactory │ ┆ ┆┆
┆ └────────┼──────────────────────────────────────┤┄┄┼┄┄┄┄┄┄┄┄┐┆┆
┆ │+ getFood(foodName: String): Food | ┆ ┆┆┆
┆ └──────────────────────────────────────┘ ┆ ┆┆┆
┆ ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘ ┆┆┆
┆ ⇣ Dependency ┆┆┆
┆ ┌──────────────────────────────────────┐ ┆┆┆
┆ │ Food │ ┆┆┆
┆ ├──────────────────────────────────────┤ ┌──────────────────────────────────────┐ ┆┆┆
┆ │- name │ Inheritance │ BBQ │ ┆┆┆
└┄┄┄⇢├──────────────────────────────────────┤⇽──────────────┬────────┼──────────────────────────────────────┤⇽┄┄┼┼┘
│+ constructor(foodName: String): void │ │ │+ constructor(foodName: String): void │ ┆┆
│+ getName(): String │ │ └──────────────────────────────────────┘ ┆┆
└──────────────────────────────────────┘ │ ┆┆
│ ┌──────────────────────────────────────┐ ┆┆
│ │ Stew │ ┆┆
├────────┼──────────────────────────────────────┤⇽┄┄┼┘
│ │+ constructor(foodName: String): void │ ┆
│ └──────────────────────────────────────┘ ┆
│ ┆
│ ┌──────────────────────────────────────┐ ┆
│ │ Drink │ ┆
└────────┼──────────────────────────────────────┤⇽┄┄┘
│+ constructor(foodName: String): void │
└──────────────────────────────────────┘
Factory
pattern 將實體化 class 這個動作封裝成另一個 factory class,專門 new 這些 class,可以使用傳入參數決定要創建哪個實例,在 simple factory
使用 condition 決定要創建哪個實例,但若要添加或刪減創建 class 的種類,需要更動 condition,違反了 OO 的 Open-Closed Principle,為了解決 simple factory
的耦合問題,factory method
將每個要創建的實例都設立一個 factory class,創建實例時只需使用相對應得 factory 來執行創建。
使用 factory method
建立食物烹煮工廠,讓廚師可以製作出飲料、烤物、燉煮類食物。
┌──────┐
│ Main │┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐ Dependency
└──────┘ ┆
┆ ┆
┆ ┌────────────────────────┐ ┆ ┌──────────────────────────────────────┐
┆ │ Factory │ Inheritance ├┄⇢│ BBQFactory │
├┄┄┄⇢├────────────────────────┤⇽────────────────────┬─────┼──┼──────────────────────────────────────┼┄┄┬┄┄┄┄┄┄┄┄┄┄┐
┆ ├────────────────────────┤ │ ┆ │+ getFood(foodName: String): Food | ┆ ┆
┆ └────────────────────────┘ │ ┆ └──────────────────────────────────────┘ ┆ ┆
┆ │ ┆ ┆ ┆
┆ │ ┆ ┌──────────────────────────────────────┐ ┆ ┆
┆ │ ├┄⇢│ StewFactory │ ┆ ┆
┆ ├─────┼──┼──────────────────────────────────────┼┄┄┼┄┄┄┄┄┄┄┄┄┐┆
┆ │ ┆ │+ getFood(foodName: String): Food | ┆ ┆┆
┆ │ ┆ └──────────────────────────────────────┘ ┆ ┆┆
┆ │ ┆ ┆ ┆┆ Dependency
┆ │ ┆ ┌──────────────────────────────────────┐ ┆ ┆┆
┆ │ └┄⇢│ DrinkFactory │ ┆ ┆┆
┆ └────────┼──────────────────────────────────────┤┄┄┼┄┄┄┄┄┄┄┄┐┆┆
┆ │+ getFood(foodName: String): Food | ┆ ┆┆┆
┆ └──────────────────────────────────────┘ ┆ ┆┆┆
┆ ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘ ┆┆┆
┆ ⇣ Dependency ┆┆┆
┆ ┌──────────────────────────────────────┐ ┆┆┆
┆ │ Food │ ┆┆┆
┆ ├──────────────────────────────────────┤ ┌──────────────────────────────────────┐ ┆┆┆
┆ │- name │ Inheritance │ BBQ │ ┆┆┆
└┄┄┄⇢├──────────────────────────────────────┤⇽──────────────┬────────┼──────────────────────────────────────┤⇽┄┄┼┼┘
│+ constructor(foodName: String): void │ │ │+ constructor(foodName: String): void │ ┆┆
│+ getName(): String │ │ └──────────────────────────────────────┘ ┆┆
└──────────────────────────────────────┘ │ ┆┆
│ ┌──────────────────────────────────────┐ ┆┆
│ │ Stew │ ┆┆
├────────┼──────────────────────────────────────┤⇽┄┄┼┘
│ │+ constructor(foodName: String): void │ ┆
│ └──────────────────────────────────────┘ ┆
│ ┆
│ ┌──────────────────────────────────────┐ ┆
│ │ Drink │ ┆
└────────┼──────────────────────────────────────┤⇽┄┄┘
│+ constructor(foodName: String): void │
└──────────────────────────────────────┘
┼ ┴ ┬ ┤ ├ ─ │ ┌ ┐ └ ┘