iOS開発では、Delegateパターンに何度も出会います。
UITableViewやUITextFieldを扱うたびにdelegateを付けながら、「なぜDelegateなんだろう?クロージャや通知ではだめなの?」と考えたことはありませんか。
特にObserverパターンまで学ぶと、かえって混乱しがちです。どちらも「何か起きたら知らせる」構造ですが、何が違うのでしょうか。
まず結論からお話しします。
Delegateは、1つのオブジェクトがただ1人に「これはあなたに任せます」と委譲する1:1の通信です。
Observerは、1つのイベントを複数人が同時に購読する1:Nのブロードキャストです。
この1行を押さえるだけで、半分は理解できます。今日はコードとともに違いを整理します。
Delegateパターンとは?
Delegateは日本語で「委譲」です。
自分で処理するのが難しい仕事を、信頼できる別のオブジェクト1つに「代わりに決めて」と任せます。
実生活にたとえると、こうです。
レストランを予約したいものの自分で電話するのが面倒なので、秘書に「代わりに予約して」と頼みます。
この秘書がDelegateです。頼む側も1人、頼まれる側も1人。まさに1:1です。
Swiftでは、これをプロトコルで定義します。
// 委譲する仕事をプロトコルで定義
protocol OrderDelegate: AnyObject {
func didFinishOrder(_ menu: String)
}
class Restaurant {
weak var delegate: OrderDelegate? // 1人だけ指定
func order(_ menu: String) {
delegate?.didFinishOrder(menu) // その1人だけに通知
}
}
ここで注目したいのは、delegateが配列ではなく、単一のプロパティだという点です。
1人に任せるので、当然1つだけ保持します。これがDelegateが1:1である理由です。
さらにweakが付いています。強参照し合うとretain cycleでメモリーリークが起きるため、Delegateは慣例的にweakで保持します。
Observerパターンとの違いは?
Observerは「観察者」です。
何かイベントが起きると、それを見ていた複数のオブザーバーに一斉に通知が届きます。
先ほどの秘書のたとえを続けましょう。
今度はレストランのオープン情報を近所に放送します。「今日の夕方にオープンします!」
聞く人は10人かもしれませんし、100人かもしれません。誰が聞くかは気にせず、ただ配信します。
これが1:Nの放送、Observerパターンです。
iOSではNotificationCenterが代表例です。
// イベント発生 → 購読者全員にブロードキャスト
NotificationCenter.default.post(name: .storeOpen, object: nil)
// 関心のあるオブジェクトが各自で購読
NotificationCenter.default.addObserver(
self, selector: #selector(handleOpen),
name: .storeOpen, object: nil)
送信側は誰が受け取るか知りません。名前を付けて投げるだけです。
受信側も複数のオブジェクトがそれぞれ購読します。
互いを知らなくてよいので結合度は低くなりますが、今誰が通知を受けているのか追跡しにくいという欠点があります。
DelegateとObserverを一目で比較
言葉だけでは混乱するので、表にまとめました。
| 区分 | Delegate | Observer |
|---|---|---|
| 通信方式 | 1:1(1人に委譲) | 1:N(複数人に放送) |
| 相手を知っているか | 互いを明確に知っている | 互いを知らなくてもよい |
| 代表例 | UITableViewDelegate | NotificationCenter |
| 応答(戻り値) | 受け取りやすい | 受け取りにくい |
| 結合度 | 比較的高い | 低い |
| 追跡・デバッグ | 容易 | やや難しい |
重要なのは「応答を返してもらう必要があるか」です。
Delegateなら「このセルの高さはいくつにする?」と聞くと、相手が値を返します。会話が往復する構造です。
Observerは投げて終わりです。誰がどう反応するか、送信側は関知しません。
結局、いつ何を使うべき?
実際のプロジェクトで使って決めた基準は次のとおりです。
Delegateを使うとき
- 1つのオブジェクトとのみ通信するとき
- 相手から値を返してもらう必要があるとき(例:セル数、高さ)
- 画面遷移のように順序と流れが明確なとき
Observerを使うとき
- 1つのイベントに複数の画面が同時に反応するとき
- ログイン状態の変更やダークモード切り替えなど、アプリ全体のイベントのとき
- 送信側と受信側が互いを知らなくてよいとき
たとえばログイン成功時にホーム画面、マイページ、上部バナーが同時に変わるなら、Delegateでは対応しきれません。
1人にしか委譲できないため、3か所すべてにつなぐとコードが煩雑になるからです。
そんなときはObserverで「ログインしたよ!」と一度だけ放送するほうが、ずっとすっきりします。
反対に「入力欄の確認ボタンを押した」のような1:1の状況なら、Delegateかクロージャが適切です。
まとめ
似て見えても、「何人に知らせるのか」を考えれば選びやすくなります。
1人ならDelegate、複数人ならObserver。この基準だけ覚えれば十分です。
次にコードを書くとき、今日学んだことを試してみてください。頭で知っていたことが手になじむ瞬間、パターンが一気に分かりやすくなります。応援しています!

