Observerパターンの代替手段
delegateやCombineのpublisherと比較します。
「Observerパターンの代替手段」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。
オブザーバーパターンの代替手段
イベントに反応する方法はNotificationCenterだけではありません。Swiftにはデリゲーション、Combine、非同期ストリームなどの方法もあります。それぞれ異なる通信の形に適しています。
オブザーバーパターン
オブザーバーパターンを使うと、オブジェクトは対象からのイベントを購読できます。NotificationCenterは、このパターンをグローバルかつ疎結合に実装したものです。
import Foundation
// Subject posts, observers react, neither holds the other.
NotificationCenter.default.post(name: Notification.Name("tick"), object: nil)
print("Broadcast an event")デリゲーション
デリゲートは1対1の接続です。オブジェクトがプロトコルを介して、特定のイベントを1つのデリゲートに転送します。明示的で、型安全な方法です。
protocol DownloadDelegate: AnyObject {
func didFinish(_ bytes: Int)
}
class Downloader {
weak var delegate: DownloadDelegate?
func finish() { delegate?.didFinish(1024) }
}
print("Delegate is one-to-one and typed")デリゲートと通知の違い
関心を持つオブジェクトが必ず1つで、関係が明確な場合はデリゲートを使います。不特定多数のオブザーバーが反応する可能性がある場合はNotificationCenterを使います。
import Foundation
// One listener -> delegate. Many/unknown listeners -> NotificationCenter.
print("Cardinality guides the choice")Combineのパブリッシャー
Combineでは、イベントをパブリッシャーとしてモデル化し、sinkで購読します。mapやfilterのような変換オペレーターにも対応しています。
import Combine
let subject = PassthroughSubject<Int, Never>()
let c = subject.sink { print("Got \($0)") }
subject.send(5)
_ = cNotificationCenterのパブリッシャー
CombineはNotificationCenterと連携できます。publisher(for:)によって通知を、変換可能なストリームに変換します。
import Foundation
import Combine
let name = Notification.Name("ping")
let c = NotificationCenter.default.publisher(for: name)
.sink { _ in print("Combine got notification") }
NotificationCenter.default.post(name: name, object: nil)
_ = cCombineのオペレーター
Combineの強みは、イベントのパイプラインを組み合わせられることです。filter、debounce、combine、mapなどを使って、値を宣言的に処理できます。
import Combine
let subject = PassthroughSubject<Int, Never>()
let c = subject
.filter { $0 > 0 }
.map { $0 * 2 }
.sink { print($0) }
subject.send(-1)
subject.send(3)
_ = c非同期シーケンス
現代のSwiftにはAsyncStreamと通知の非同期シーケンスがあり、構造化された並行処理の中でfor awaitを使ってイベントを消費できます。
import Foundation
func listen() async {
let name = Notification.Name("ping")
for await _ in NotificationCenter.default.notifications(named: name) {
print("Async observed")
break
}
}
print("Can await notifications")クロージャとコールバック
単一のローカルなコールバックには、オブザーバーの仕組みを一切使わない、保存したクロージャが最も簡単です。
struct Button {
var onTap: () -> Void
func tap() { onTap() }
}
Button(onTap: { print("tapped") }).tap()方法を選ぶ
デリゲート:1対1で明示的です。NotificationCenter:多対多で疎結合です。Combine/非同期:変換が必要なストリーム向けです。クロージャ:単純なローカルコールバック向けです。
import Foundation
// Match the tool to the communication shape.
print("Delegate, Notification, Combine, async, closure")トレードオフ
NotificationCenterは柔軟ですが、型付けがなく、リークも起きやすい仕組みです。デリゲーションとCombineは型安全です。Combineと非同期処理は、より多くの概念を学ぶ代わりに高い柔軟性を得られます。
import Foundation
// Prefer typed approaches when the relationship is known.
print("Type safety vs flexibility tradeoff")理解度チェック
明確な1対1の型安全な関係には、どの仕組みが最適ですか?
まとめ
オブザーバーパターンには、Swiftでいくつかの形があります。疎結合な多対多のイベントにはNotificationCenter、型付きの1対1の接続にはデリゲーション、組み合わせ可能なストリームにはCombineと非同期シーケンス、単純なコールバックにはクロージャを使います。通信の形と型安全性の要件に応じて選択します。これでコースは完了です。
よくある質問
「Observerパターンの代替手段」レッスンは無料ですか?
はい。「Observerパターンの代替手段」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。
「Observerパターンの代替手段」で何を学びますか?
delegateやCombineのpublisherと比較します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Swift Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「Observerパターンの代替手段」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSwift Academyレッスンでコードを書いて実行できますか?
はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 通知の投稿と監視
- NotificationのuserInfoペイロード
- オブザーバーの安全な削除
- Observerパターンの代替手段