---
# System prepended metadata

title: solid
tags: [iOS_軟體架構]

---

# solid

###### tags: `iOS_軟體架構`

### single responsibility principle

讓一個東西只負責單一的職責，有變更的地方就有bug，當一個類只有一個功能，功能要更動時只會動到相關的類或模組，這樣可以減少動到的部分，降低不確定因素和 bug 出現的可能性。

舉例：
登入流程的UIViewController只負責畫面呈現，切換頁面使用lazy var router，呼叫api使用APIService()，跳出UIAlertController做成static的show方法

![](https://i.imgur.com/e4ZO0f6.png)



### Open Close Principle

其宗旨是把程式撰寫成，當需要新增新的功能時，不需要靠修改原有的程式碼，而是在原有的程式碼上加上寫新的程式碼即可。

舉例：
1. 多型：透過繼承，override父類別func，減少判斷式
```swift=
class Animal {
    func eat() -> String {
        return "吃肉"
    }
}

class Cat: Animal {
    override func eat() -> String {
        return "吃魚"
    }
}

class Dog: Animal {
    override func eat() -> String {
        return "吃狗糧"
    }
}

class ActionManager {

    func eat(animal: Animal) {
        print(animal.eat())
    }
}

var action = ActionManager()
var cat = Cat()
action.eat(animal: cat)

var dog = Dog()
action.eat(animal: dog)

```


3. protocol：在ViewController init的時候把不同的protocol實例塞進去，以拿到不同的回傳資料

![](https://i.imgur.com/HM4X2Sc.png)



### Liskov Substitution Principle

宗旨1：子類的功能應該只是父類的加強，不該不一樣，舉例：父類寫資料進userDefault，子類加密後寫入userDefault，不應該改成寫入別的地方

宗旨2：子類繼承後，應該要滿足父類的功能，要馬把父類的功能抄過來，要馬使用 super.function()


 ### Interface Segregation Principle
 
如果 User1 只需要使用 operation1 方法，User2 只需要使用 operation2 方法，User3 只需要使用 operation3 方法，那麼很明顯對於 User1 來說，不應該看到 operation2 和 operation3 這兩個方法，要減少對自己不關心的方法的依賴，防止 Operation 類中 operation2 和 operation3 方法的修改，影響到 User1 的功能。

![](https://i.imgur.com/YfujeKe.png)

舉例：

假如一個ITprotocol有writeCode, writeDocument, manage三個function，假如工程師繼承ITprotocol要特別註記他不會manage，主管繼承ITprotocol要特別註記他不會writeCode

不如就乾脆先建一個ITprotocol裡頭只有writeDocument，再建DevelopmentProtocol繼承ITProtocol加入writeCode & ManageProtocol繼承ITProtocol加入manage

這樣Programmer繼承DevelopmentProtocol只需實作writeCode & writeDocument

Manager繼承ManageProtocol只需實作Manage & writeDocument


###  Dependency Inversion Principle

依賴倒置原則的目的是通過面向protocol的程式設計來降低類間的耦合性

原始程式碼：
```swift=
class StarHotel {
    func live() {
        print("StarHotel live")
    }
}

class Homestay {
    func live() {
        print("Homestay live")
    }
}

class Traveler {
    func booking(_ starHotel: StarHotel) {
        starHotel.live()
    }

    func booking(_ homeStey: Homestay) {
        homeStey.live()
    }
}

//呼叫程式碼
var traveler = Traveler()
var starHotel = StarHotel()
var homestay = Homestay()
traveler.booking(starHotel)
traveler.booking(homestay)

/**
呼叫結果：

StarHotel live
Homestay live

**/
```
缺點：
1. 如果又有其它型別酒店可以提供，我們又得在Traveler這個類，新增一個酒店的預訂方法
2. 耦合性太強了，旅客類Traveler和星級酒店StarHotel，名宿Homestay都有相互依賴

遵從Dependency Inversion Principle的做法：
```swift=
protocol HotelProtocol {
    /// 居住
    func live()
}

/// 名宿
class Homestay: HotelProtocol {
    func live() {
        print("Homestay live")
    }
}


/// 星級酒店
class StarHotel: HotelProtocol {
    func live() {
        print("StarHotel live")
    }
}

/// 旅客
class Traveler {

    func booking(_ hotel: HotelProtocol) {
        hotel.live()
    }
}

var traveler = Traveler()
var starHotel = StarHotel()
var homestay = Homestay()
traveler.booking(starHotel)
traveler.booking(homestay)

/**

呼叫結果：

StarHotel live
Homestay live

**/

```


資料參考來源：

[DIP](https://www.gushiciku.cn/pl/ag8d/zh-tw)

[工作那麼久，才知道的 SOLID 設計原則](https://codingnote.cc/zh-tw/p/150124/)

[架构之路 （七） —— iOS App的SOLID原则（一）](https://www.jianshu.com/p/6edc405cedf6)

[SOLID raywenderlich](https://www.raywenderlich.com/21503974-solid-principles-for-ios-apps)

[SOLID 之 S — 單一職責原則](https://medium.com/@nwyyy/solid-%E4%B9%8B-s-%E5%96%AE%E4%B8%80%E8%81%B7%E8%B2%AC%E5%8E%9F%E5%89%87-305b9ad65e6f)

[SOLID 之 O — 開放封閉原則](https://medium.com/@nwyyy/solid-%E4%B9%8B-o-%E9%96%8B%E6%94%BE%E5%B0%81%E9%96%89%E5%8E%9F%E5%89%87-a9f1fd5bcd1f)

[OCP](https://www.gushiciku.cn/pl/apeZ/zh-tw)

[SOLID 之 L — 里氏替換原則](https://medium.com/@nwyyy/liskov-substitution-principle-85594a75b3d1)
