GoF以外のプログラミング・デザインパターン #08 Reactor Pattern

2025/11/29

プログラミング 学習

t f B! P L
eyecatch 「Reactorパターン」は、イベント駆動(Event-driven)型の設計パターンで、サーバーやネットワーク通信など「I/O多重処理(非同期処理)」に使われる非常に重要なパターンです。 このデザインパターンの目的としては、次のような感じです。
・多数の入出力(I/O)イベントを効率的に扱う。 ・同時接続をスレッド爆発させずに処理させる。 ・各イベントの処理を「ハンドラ」に委譲する。
一言で言うと、「1つのイベントループで多数のI/Oイベントを効率的にさばくための設計構造」です。

基本構造

Reactor (イベントループ) ┌──────────┐ │ Demultiplexer   │ ← OSが提供するselect/poll/epoll/kqueue等 └──────────┘ │ [イベント検出] │ Dispatch ↓ [Handler呼び出し]

主要コンポーネント

コンポーネント 役割
Reactor イベントを待ち受け、発生したイベントを対応するハンドラへディスパッチ
Handler 各種イベント(accept / read / write)を処理
Demultiplexer OSレベルでI/Oイベントを監視(`select()` や `epoll_wait()`など)

処理の流れ(概略)

1. Reactor がイベントを監視 (select や poll を使用) 2. イベントが発生すると、対応するHandlerを呼び出す 3. Handler が実際の処理(受信・送信・応答など)を実行

サンプルコード

Node.jsのイベントループは、まさにReactorパターンの実装例です。 const net = require('net'); // === Reactor: イベントループでI/Oを待ち受け === const server = net.createServer((socket) => { console.log('クライアント接続'); // === Handler: データ受信イベント === socket.on('data', (data) => { console.log('受信:', data.toString()); socket.write('受信しました!'); }); // === Handler: 接続終了イベント === socket.on('end', () => { console.log('接続終了'); }); }); server.listen(3000, () => { console.log('Reactorサーバー起動中 (port 3000)'); }); Node.jsでは内部的に「libuv」というCライブラリがepoll/kqueueを使ってReactorパターンを実装しています。

メリット

・スレッド数が少なくても高い同時接続性能を持つ ・ノンブロッキングI/Oによる高スループット ・イベント処理を明確に分離できる(Handler単位)

デメリット

・コード構造がコールバック地獄になりやすい(特に言語サポートが弱い場合) ・イベント駆動モデルの理解が必要(命令型に慣れた開発者には直感的でない) ・各Handlerが重い処理を行うと、全体のイベント処理が滞る(非同期設計が重要)

関連パターン

パターン 違い・関連性
Proactor Reactorが「イベント検出 → 処理開始」なのに対し、Proactorは「OSが処理完了後に通知」するパターン(例:WindowsのIOCP)
Observer ReactorはI/Oイベントに特化したObserverパターンの一種
Event Loop Reactorの中核的構造。JavaScriptやPythonのasyncioもこの考え方を採用

あとがき

Nodeでは標準的に使う、Serverソケットの構造パターンですね。 イベント発火からのハンドラーへの接続は、Javascript特有で使用しますが、慣れていないとこの設計が乱雑になりがちです。 Reactorフレームワーク自体を参考にしなくても、ネイティブJavascriptでもクリックや、スクロールなどのイベント発火で応用できるので、Webエンジニアやアプリエンジニアであれば、理解しておくべきデザインパターンですね。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ