---
# System prepended metadata

title: classical system design pattern
tags: [公開文檔]

---

[中文版在此：](https://vocus.cc/article/67bafcecfd897800011d89b1)
{%preview https://vocus.cc/article/67bafcecfd897800011d89b1 %}

## System design
### SOLID rules for OOP

| Principle | Description | simple words | e.g. |
| --- | --- | --- | --- |
| **S**ingle responsibility principle | A module should be responsible to one, and only one, actor. | _i.e. <span style='color: #fa8072;'>one module one function</span>_ | `login` module shall not has transaction function |
| **O**pen-closed principle | software entities (classes, modules, functions, etc.) should be `open for extension`, but `closed for modification` | _i.e. <span style='color: #fa8072;'>open for extension, closed for modification</span>_ | If we wanna add a function for Paypal, create a new check function instead of modifying the current one |
| **L**iskov substitution principle | replacing a superclass object with a subclass one shall not affect the system's correctness | _i.e <span style='color: #fa8072'>offspring shall bear all traits its parents have</span>_ <br> ![car example for Liskov substitution principle](https://resize-image.vocus.cc/resize?compression=6&norotation=true&url=https%3A%2F%2Fimages.vocus.cc%2F239230cf-4eb2-4cfe-95f8-ec29114ac41d.png&width=740&sign=GdQ25f6dCpK7UfMyiNcaaG9NgpxpeSmo0vMdWgMkLb8) | a lorry bears all features a car shall have, but a car doesn't |
| **I**nterface segregation principle | A client should never be forced to implement an interface that it doesn't use | _i.e. <span style='color: #fa8072;'>throw out irrelevant or unnecessary functions from the interface</span>_ | There is an printer interface with `print` and `scan` methods. If Woof only has `scan` demand, we shall not force him to implement the interface containing `print` |
| **D**ependency inversion principle | High-level modules should not import anything from low-level modules. Both should depend on abstractions (e.g., interfaces).<br> Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions. | _i.e. <span style='color: #fa8072;'>change anything in lower-module shouldn't affect the higher ones</span>_ | Someday Ibi finds his PS5 controller broken, he just needs to buy a new controller rather than the whole PS5 set since PS5 doesn't rely on its controller |

---

## Common design pattern

| Design pattern | simple description | analogy in real life |
| --- | --- | --- |
| Prototype | creating by cloning | write CV from template |
| Singleton | One class one global-accessible instance | government |
| factory | order -> objects, without knowing the manufacturing process | order an iphone _Rarely do people know how their iPhone is made_ |
| Abstract Factory | factory's blueprint | the blueprint of Giant's factories |
| Builder | Separation of production processes | Ford car's manufacture |
| Dependency Injection | functions outsourcing | putting a battery in the phone instead of co-production |

### Prototype Pattern
![prototype pattern illustration](https://resize-image.vocus.cc/resize?compression=6&norotation=true&url=https%3A%2F%2Fimages.vocus.cc%2Fd8f0c7c7-6ada-497b-b4f7-6e52613a333c.png&width=740&sign=LVsXC_saPRmmH6HNNgZJ--4JpwJ4q2H5YBzNznV28bQ)
<span style='font-size: 0.64em;'>source: Ibi, i.e. me</span>

* Definition: creating objects by cloning rather than instantiating a whole new one
_Just like using template_
* Why?
    * Efficiency
    * Management
    If you want to make some adjustion, you only need to modify the template
* Example:
    * `Ctrl` + `C` -> `Ctrl` + `V`
    * Using a template to write Curriculum Vitae instead of scratching from a blank sheet
### Singleton
<!-- https://refactoring.guru/design-patterns/singleton -->
![Singleton illustration](https://resize-image.vocus.cc/resize?compression=6&norotation=true&url=https%3A%2F%2Fimages.vocus.cc%2Fdd5f370b-1c9c-44ee-a63f-4a5f6f2113b9.png&width=740&sign=VAlFS20_pGlZaBQAQzl7x2oRI6eDPEBfVzrvJFFa7jc)
<span style='font-size: 0.64em;'>source: Ibi, i.e. me</span>

* definition:
    * One class one instance
    * global access point
* Why?
    * Resource sharing
    * Instantiation efficiency
    some objects may require higher cost for instantiation
    * Management convenience
    one access point for all objects
* Examples:
    * DB connection pool
    * Log system
    * config file manager
    * Government
* cons:
    * Violating **Single responsibility principle**
    * High coupling level
    -> difficulty for unit test
    -> modification may affect other functions
    * global variable corruption
    * multi-thread safety - - -> Double-Checked Locking Pattern (lock hint) 
### Factory Pattern
* Definition: 
  Separation of production and utilisation
_users don't need to know the producing process, just giving order_
* How?
    * Object creation:
        The main goal is to create objects
    * Abstraction:
        You don't need to know the specific details in production process
    * Separation of Concern:
        User knows nothing about how their object created, leading to cleaner code and higher maintainability
* Why?
    * Flexibility:
        New types of objects are able to be made without downstream code modification
    * Maintainability
    * Code Clarity
* Real-life example:
    * Pizza making: 
        Recall the last time you ordered a pizza. You just needed to say what you like to eat, rather than **how the pizza shall be made**, right?
    * Car factory: 
        When purchasing a car, buyers only have to tell seller what they want. **How** the car pops up isn't important

### Abstract Factory Pattern
* Definition: 
    The blueprint for factories, i.e. factories' factory
* Purpose: 
    Creating families of related objects without specifying their concrete classes
* Relationship: 
    * Abstract factory
        * factories
            * objects
* Example:
    * GUI design blueprint: abstract factory
    * GUI for Windows: factory
        * some buttons: objects
    * GUI for Mac: factory
        * some buttons: objects

### Builder Pattern
![builder pattern illustration](https://resize-image.vocus.cc/resize?compression=6&norotation=true&url=https%3A%2F%2Fimages.vocus.cc%2F240c9346-34b2-437b-8ea5-d79af911f8f8.png&width=740&sign=UVaPVEUScU_ps4U2JOOoqupfoEJm-VJHqqwQ4ZWKpk8)
<span style='font-size: 0.64em;'>source: Ibi, i.e. me</span>

* Definition: Separation of production processes
* Why?
    * Make a complex thing all at once may be difficult, while do it stepwise can be much easier
    * Avoiding **telescoping constructors**
    _Several constructors in the same class just for different parameter number acceptance, thus an anti-pattern_
* How?
    * One step one builder, and they only need to do their own job
* Real-life example:
    * When building a computer, its components such as CPU, GPU, RAM, etc. are made in different places before assembly

### Dependency Injection (DI) Pattern
![dependency injection pattern illustration](https://resize-image.vocus.cc/resize?compression=6&norotation=true&url=https%3A%2F%2Fimages.vocus.cc%2F189d115d-4074-4263-ac03-f609e5b6f224.png&width=740&sign=i5cWfPgtpCFNrqoj7Su0Wx0KEADyT6gAnTTYRK_8S_4)
<span style='font-size: 0.64em;'>source: Ibi, i.e. me</span>

* Principle: Module/class gets its required functions from outside, rather than creating them itself
* Terminology
    * Dependency: the requirement for something to perform some functions
    e.g. A car _depends_ an engine to run => engine is the car's dependency
    * Injection: giving something from outside into an entity
    e.g. Placing a battery into a phone instead of making it a part of a phone ~~like modern smart phone~~
* Why?
    * loose coupling
    * Flexibility
    * Higher testability
    * Cleaner code

---

## Design patterns for service

### 3-tier architecture
![three-tier architecture figure: ](https://www.researchgate.net/profile/Muhammad-Ehsan-Rana/publication/357819645/figure/fig1/AS:1120708604231682@1644209161532/Tier-Architecture-Pattern.jpg)
<span style='font-size: 0.64em;'>source: Muaz, Abdulla & Rana, Muhammad Ehsan & Hameed, Vazeerudeen. (2021). A Framework for Catering Software Complexity Issues Using Architectural Patterns. 554-561. 10.1109/IEEECONF53624.2021.9668115.</span>
* presentation tier (client end)
* business logic tier (server)
* Data access tier (database)
* why use 3-tier architecture?
    * Separation of Concerns -> maintainability
    * Scalability
    * Security
    * Reusability
    * Decoupling

### MVC
**M**odel-**V**iew-**C**ontroller
* Model: business-logic-handling programme
* View: GUI module
* Controller: task-assigning programme

### MVP
**M**odel-**V**iew-**P**resenter
* Model: business-logic-handling programme
* View: GUI module
* Presenter: handling the data and sending it to View

### MVVM
**M**odel-**V**iew-**V**iew**M**odel
* Model: business-logic-handling programme
* View: GUI module
* ViewModel: process the data into view-format
    * Binder connects the Data and View
    * Data change in ViewModel will affect view
_ViewModel can be unit-tested independently, real-UI is unnecessary during the unit test_

### Summary
| Sub-structure | Presentation tier | Logic tier | Data tier |
| :---: | :---: | :---: | :---: |
| MVC | View (GUI) | Model and Controller | Database |
| MVP | View | Model and Presenter | Database |
| MVVM | View | ViewModel and Model | Database |




<!-- ## 常見設計模式

| 設計模式 | 這什麼？ | 生活類比 |
| --- | --- | --- |
| 原型 (Prototype) | 複製 \+ 修改 \= 創建 | 用模板寫履歷 |
| 單例 (Singleton) | 一個類別，一個全域可存取的實例 | 政府機關 |
| 工廠 (Factory) | 下訂單 -> 物件，無需了解製造過程 | 訂購 iPhone _很少買家知道 iPhone 生產細節_ |
| 抽象工廠 (Abstract Factory) | 工廠的藍圖 | 捷安特工廠藍圖 |
| 製造者 (Builder) | 生產流程的分離 | 福特式生產 (流水線工人各自負責拆解後的工作) |
| 相依性注入 (Dependency Injection) | 函數外包 | 給手機裝電池，而非把電池做在手機上 | -->

<!-- | 子結構 | 展示層 (Presentation tier) | 商業邏輯層 (Logic tier) | 資料層 (Data tier) |
| :---: | :---: | --- | :---: |
| MVC (模型-視圖-控制器) | 視圖 (GUI View) | 模型 (Model) 與 控制器 (Controller) | 資料庫 (Database) |
| MVP (模型-視圖-展示器) | 視圖 (View) | 模型 (Model) 與 呈現者 (Presenter) | 資料庫 (Database) |
| MVVM (模型-視圖-視圖模型) | 視圖 (View) | 視圖模型 (ViewModel) 與 模型 (Model) | 資料庫 (Database) | -->

