0Pricing
Swift Academy · レッスン

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)
_ = c

NotificationCenterのパブリッシャー

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)
_ = c

Combineのオペレーター

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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 通知の投稿と監視
  2. NotificationのuserInfoペイロード
  3. オブザーバーの安全な削除
  4. Observerパターンの代替手段
← Swift Academyに戻る