iOS常用的Design Pattern

更新於 發佈於 閱讀時間約 10 分鐘

記錄個人常用的Design Pattern,之前面試被問到有用過哪些,瞬間一片空白🥹

以下有寫iOS應該都用過,只是可能講不出這算哪個Pattern

MVC vs. MVVM

詳情在前一篇學習筆記

單例模式 Singleton

確保一個class只能創建一個實例,並提供全域訪問。一般我會用在單一狀態管理上,例如:資料庫連結、登入狀態管理

通常包含以下特點:

  1. 私有構造函數(Private Constructor): Singleton類別的init通常是私有的,以防止外部代碼通過實例化多個對象。
  2. 靜態實例(Static Instance): Singleton類別包含一個靜態成員,用於保存該類別的唯一實例。
  3. 全域訪問點(Global Access Point): 提供一個全域的訪問點,使得其他程式碼可以獲取Singleton實例的引用。

範例:管理登入狀態的Manager。

class LoginManager {
static let shared = LoginManager()
var isLogin = false

private init() {}

func login() {
isLogin = true
}

func logout() {
isLogin = false
}
}


委派模式 Delegation pattern

一個物件把一些職責讓另一個物件來執行。這個Apple官方自己也很常用。

範例:UITableViewDelegate,把TableView的一些行為(如:點擊)給ViewController來代理

class VC1: UIViewController{
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
tableView.delegate = self
}
}

extension VC1: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// 點擊後讓VC做一些事
}
}


觀察者模式 Observer Pattern

通知:Notification

這個Apple官方也很常用,例如:鍵盤彈起(UIKeyboardWillShowNotification)收合(UIKeyboardWillHideNotification),或是AppDelegate各種生命週期通知。

這種通知是全域的,發布者不需要知道訂閱者的任何資訊。

鍵值觀察:Key-Value Observing (KVO)

一種機制,允許一個物件可以註冊監聽其他物件指定屬性的變化。

這邊要介紹一下Combine的KVOpublisher(for: \.KeyProperty),我覺得在UIKit上超好用ㄉ

範例:監聽UITabBarController的TabBar.isHidden

import Combine
class MyTabBarController: UITabBarController {
private var subscriptions = Set<AnyCancellable>()
override func viewDidLoad() {
super.viewDidLoad()
setBinding()
}

private func setBinding() {
self.tabBar.publisher(for: \.isHidden).sink { [weak self] hidden in
if !hidden {
// 如果Tabbar可見,在Bar上show一條InfoView
self?.showInfoView()
} else {
// 反之隱藏
self?.hideInfoView()
}
}
}.store(in: &subscriptions)
}

Delegate 和 Notification 使用時機

兩個都可以拿來在App裡通訊傳值,但使用時機略有不同

Delegate 的使用時機

  • 一對一:通常是一個委託人對到一個委託對象。
  • 有明確的行為:通常會訂個protocol,讓委託對象實現其中的方法,以達到客製化行為的目的。

Notification 的使用時機

  • 一對多:一個發送通知的對象可以通知多個觀察者。
  • 非特定行為: Notification 通常用於通知一個事件的發生,而不關心具體的行為。多個不同的觀察者可以對同一事件進行不同的反應。

Delegate可不可以一對多?

也可以。通常是一對一,如果要一對多,自己寫Array來保存多個觀察者。通常我會用在有明確行為,又只有兩三個地方需要接受這個訊息的情況下。

範例:Socket連線,當Socket連線狀態產生變化時,要通知底下所有有註冊他的委託對象(聊天室列表&聊天室頁面)​

// 觀察者
class WeakSocketObserver {
weak var value: SocketDelegate?
init (value: SocketDelegate) {
self.value = value
}
}

// 定義Socket連線狀態的協議
protocol SocketDelegate: AnyObject {
// 連線成功
func didConnected()
// 其他狀態省略
// ...
}

Socket本人(委託人)

import SocketIO
@objc class MySocket: NSObject {
@objc static let shared = MySocket()
private var manager: SocketManager()
private var socket: SocketIOClient!
// 所有觀察者
private var observers: [WeakSocketObserver] = []

private override init() {
super.init()
// ...
socket = manager.defaultSocket
socket.on(clientEvent: .connect) { (data, ack) in
// 連線成功時,通知所有觀察者
self.observers.forEach { (observer) in
observer.value?.didConnected()
}
}
}


func tryConnect() {
// 開始連線
}
}

加入委託對象(觀察者)

// 第一個觀察者​-聊天列表
class ChatroomListVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Socket加入觀察者
MySocket.shared.add(WeakSocketObserver(value: self))
// 嘗試連線
MySocket.shared.tryConnect()
}
}

extensionChatroomListVC: SocketDelegate {
func didConnected() {
// 我連線了!
}
}

// 第二個觀察者​​-聊天室
class ChatroomVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Socket加入觀察者
MySocket.shared.add(WeakSocketObserver(value: self))
// 嘗試連線
MySocket.shared.tryConnect()
}
}

extensionChatroomVC: SocketDelegate {
func didConnected() {
// 我連線了!
}
}

Socket連線後,底下的聊天室跟聊天列表都會收到通知。




參考資料:

ChatGPT

https://wilden-chen.gitbook.io/swift-design-patterns



留言
avatar-img
留言分享你的想法!
avatar-img
Michelle Chen的沙龍
8會員
34內容數
紀錄iOS開發上遇到的問題或是一些流程筆記。主要都是Swift。
Michelle Chen的沙龍的其他內容
2024/09/06
本文介紹了使用KeyboardLayoutGuide的方法,以及在不同iOS版本和設備上遇到的佈局問題。透過調整TextView的底部對齊方式,成功解決了在模擬器和真實設備上出現的錯誤,提供了有用的建議給開發者。本文還探討了為何在iOS15與Xib的組合使用中會出現問題,以及解決方案。
Thumbnail
2024/09/06
本文介紹了使用KeyboardLayoutGuide的方法,以及在不同iOS版本和設備上遇到的佈局問題。透過調整TextView的底部對齊方式,成功解決了在模擬器和真實設備上出現的錯誤,提供了有用的建議給開發者。本文還探討了為何在iOS15與Xib的組合使用中會出現問題,以及解決方案。
Thumbnail
2024/08/07
使用者回報的超級奇怪線上問題,用數字鍵盤(NumberPad)更改欄位時,送出後尾數都會消失。例如:30 ⭢ 3,52 ⭢ 5。 尋尋覓覓了兩天終於被我找到這篇,apple的奇葩的bug 重現條件 iOS17 手機設定是繁體中文語系 前一個用過的鍵盤是Cangjie倉頡 or Suchen
2024/08/07
使用者回報的超級奇怪線上問題,用數字鍵盤(NumberPad)更改欄位時,送出後尾數都會消失。例如:30 ⭢ 3,52 ⭢ 5。 尋尋覓覓了兩天終於被我找到這篇,apple的奇葩的bug 重現條件 iOS17 手機設定是繁體中文語系 前一個用過的鍵盤是Cangjie倉頡 or Suchen
2024/07/03
這篇文章探討瞭如何在iOS應用程式中客製化Alert,包括改變字體大小、內嵌連結以及讓Alert的高度隨著字數增長並提供scroll操作。同時使用SwiftUI進行客製化,並介紹瞭解決高度超出範圍後文字捲動與scrollView固定高度的方法。
Thumbnail
2024/07/03
這篇文章探討瞭如何在iOS應用程式中客製化Alert,包括改變字體大小、內嵌連結以及讓Alert的高度隨著字數增長並提供scroll操作。同時使用SwiftUI進行客製化,並介紹瞭解決高度超出範圍後文字捲動與scrollView固定高度的方法。
Thumbnail
看更多
你可能也想看
Thumbnail
「欸!這是在哪裡買的?求連結 🥺」 誰叫你太有品味,一發就讓大家跟著剁手手? 讓你回購再回購的生活好物,是時候該介紹出場了吧! 「開箱你的美好生活」現正召喚各路好物的開箱使者 🤩
Thumbnail
「欸!這是在哪裡買的?求連結 🥺」 誰叫你太有品味,一發就讓大家跟著剁手手? 讓你回購再回購的生活好物,是時候該介紹出場了吧! 「開箱你的美好生活」現正召喚各路好物的開箱使者 🤩
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
Thumbnail
需求情境: 在設計畫面時,資料來源是後台的 api,每一次畫面細節的修修改改,都會觸發 Xcode Preview 程序,導致不斷呼叫後台。此時若資料結構和大小都具有一定規模,就會導致效率低落,不斷等待,且消耗伺服器資源甚鉅。 解決方案: 將後台傳回的資料以檔案形式暫存在本地端,每次 pr
Thumbnail
需求情境: 在設計畫面時,資料來源是後台的 api,每一次畫面細節的修修改改,都會觸發 Xcode Preview 程序,導致不斷呼叫後台。此時若資料結構和大小都具有一定規模,就會導致效率低落,不斷等待,且消耗伺服器資源甚鉅。 解決方案: 將後台傳回的資料以檔案形式暫存在本地端,每次 pr
Thumbnail
Part.1 搞定基本的 UI 開始開發 iOS App。 首先準備一台 Mac,然後安裝 Xcode,新增專案,系統即刻生成基本的專案結構。coding 的起點在檔案 ContentView.swift: import SwiftUI struct ContentView: View {  
Thumbnail
Part.1 搞定基本的 UI 開始開發 iOS App。 首先準備一台 Mac,然後安裝 Xcode,新增專案,系統即刻生成基本的專案結構。coding 的起點在檔案 ContentView.swift: import SwiftUI struct ContentView: View {  
Thumbnail
本篇文章將分享手機App設計教學,並往後介紹使用Flutter開發App的相關知識和技巧。透過這系列的分享,讀者將能夠學習如何利用設計和程式開發技能來製作一個App。文章中也提供了一些靈感來源和教學資源,幫助讀者進行設計和開發的思考和學習。
Thumbnail
本篇文章將分享手機App設計教學,並往後介紹使用Flutter開發App的相關知識和技巧。透過這系列的分享,讀者將能夠學習如何利用設計和程式開發技能來製作一個App。文章中也提供了一些靈感來源和教學資源,幫助讀者進行設計和開發的思考和學習。
Thumbnail
樣板模式的定義極為簡單,卻是大型系統程式、WEB/APP應用框架的設計核心,完美展現設計模式的價值: 簡單、高效、強大。
Thumbnail
樣板模式的定義極為簡單,卻是大型系統程式、WEB/APP應用框架的設計核心,完美展現設計模式的價值: 簡單、高效、強大。
Thumbnail
本書大多數的內容都以 OO 的概念出發,詳列了許多設計的臭味道,也有大量的例子。個人雖然不會這樣寫程式,但仍是覺得受益良多,至少在 code review 時能更清楚知道該怎麼描述問題。不過,即便不是用 OO 的概念,有些章節還是可以帶來一些想法,用 OO 概念寫程式的人更不該錯過這本好書。
Thumbnail
本書大多數的內容都以 OO 的概念出發,詳列了許多設計的臭味道,也有大量的例子。個人雖然不會這樣寫程式,但仍是覺得受益良多,至少在 code review 時能更清楚知道該怎麼描述問題。不過,即便不是用 OO 的概念,有些章節還是可以帶來一些想法,用 OO 概念寫程式的人更不該錯過這本好書。
Thumbnail
觀察者模式透過主題訂閱/訊息通知的機制,極度增強系統的可擴展性、靈活性以及降低組件間的耦合度。概念直觀簡單,是非常實用的設計模式。
Thumbnail
觀察者模式透過主題訂閱/訊息通知的機制,極度增強系統的可擴展性、靈活性以及降低組件間的耦合度。概念直觀簡單,是非常實用的設計模式。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News