Chain_of_Responsibility_パターン
[Wikipedia|▼Menu]

Chain-of-responsibility パターン, CoR パターンは、オブジェクト指向設計におけるデザインパターンの一つであり、一つのコマンドオブジェクトと一連の処理オブジェクト (processing objects) から構成される。各処理オブジェクトは、処理できるコマンドオブジェクトの種類と、自身が処理できないコマンドオブジェクトをチェーン内の次の処理オブジェクトに渡す方法を記述する情報を保持する。また、新たな処理オブジェクトをチェーンの最後に追加する機構を備える。

標準的な chain-of-responsibility のモデルの派生ハンドラーがディスパッチャとして動作し、コマンドを様々な方向に送出できるようにすることで、いわば tree of responsibility を形成しているものもある。

また、これを再帰的に行うケースもあり、処理オブジェクトが上位の処理オブジェクトを、問題の一部を解決するコマンドとともに呼び出すこともある。こうした場合再帰はコマンドが処理されるか、全てのツリーを巡回するまで継続される。XMLのインタプリタ(パースはするが実行はしない)などがこの例に当てはまるだろう。

このパターンはプログラミングにおいてよく用いられる、疎結合性を促進させる方法である。
目次

1 例

1.1 Java

1.2 PHP


2 関連項目

3 外部リンク


Java

以下の Java コードは、ロギングクラスの例を用いてこのパターンを示したものである。各ロギングハンドラーはログレベルで何らかのアクションを起こすべきかどうかを判断し、次のロギングハンドラーにメッセージを渡す。

出力: Writing to debug output: Entering function y. Writing to debug output: Step1 completed. Sending via e-mail: Step1 completed. Writing to debug output: An error has occurred. Sending via e-mail: An error has occurred. Writing to stderr: An error has occurred.


この例はロギングクラスをこの方法で書くことを推奨するものではなく、また、CoR の「純粋な」実装では、ロガーがメッセージを処理した後に、その責任を後段に渡すことはない。この例では処理されるかどうかに関係なく、メッセージがチェーンの先に渡される。import java.util.*;abstract class Logger { public static final int ERROR = 3; public static final int NOTICE = 5; public static final int DEBUG = 7; private final int mask; protected Logger(int mask) { this.mask = mask; } // The next element in the chain of responsibility protected Logger next; public Logger setNext(Logger l) { next = l; return this; } public void message(String msg, int priority) { if (priority <= mask) { writeMessage(msg); if (next != null) { next.message(msg, priority); } } } abstract protected void writeMessage(String msg);}class StdoutLogger extends Logger { public StdoutLogger(int mask) { super(mask); } @Override protected void writeMessage(String msg) { System.out.println("Writting to stdout: " + msg); }}class EmailLogger extends Logger { public EmailLogger(int mask) { super(mask); } @Override protected void writeMessage(String msg) { System.out.println("Sending via email: " + msg); }}class StderrLogger extends Logger { public StderrLogger(int mask) { super(mask); } @Override protected void writeMessage(String msg) { System.out.println("Sending to stderr: " + msg); }}public class ChainOfResponsibilityExample { public static void main(String[] args) { // Build the chain of responsibility final Logger l = new StdoutLogger(Logger.DEBUG).setNext( new EmailLogger(Logger.NOTICE).setNext( new StderrLogger(Logger.ERROR))); // Handled by StdoutLogger l.message("Entering function y.", Logger.DEBUG); // Handled by StdoutLogger and EmailLogger l.message("Step1 completed.", Logger.NOTICE); // Handled by all three loggers l.message("An error has occurred.", Logger.ERROR); }}
PHP<?phpabstract class Logger { const ERR = 3; const NOTICE = 5; const DEBUG = 7; protected $mask; protected $next; // The next element in the chain of responsibility public function setNext(Logger $l) { $this->next = $l; return $this; } abstract public function message($msg, $priority);}class DebugLogger extends Logger { public function __construct($mask) { $this->mask = $mask; } public function message($msg, $priority) { if ($priority <= $this->mask) { echo "Writing to debug output: {$msg}\n"; } if (false == is_null($this->next)) { $this->next->message($msg, $priority); } }}class EmailLogger extends Logger { public function __construct($mask) { $this->mask = $mask; } public function message($msg, $priority) { if ($priority <= $this->mask) { echo "Sending via email: {$msg}\n"; } if (false == is_null($this->next)) { $this->next->message($msg, $priority); } }}class StderrLogger extends Logger { public function __construct($mask) { $this->mask = $mask; } public function message($msg, $priority) { if ($priority <= $this->mask) { echo "Writing to stderr: {$msg}\n"; } if (false == is_null($this->next)) { $this->next->message($msg, $priority); } }}class ChainOfResponsibilityExample { public function __construct() { // build the chain of responsibility $l = new DebugLogger(Logger::DEBUG); $e = new EmailLogger(Logger::NOTICE); $s = new StderrLogger(Logger::ERR); $e->setNext($s); $l->setNext($e); $l->message("Entering function y.", Logger::DEBUG); // handled by DebugLogger $l->message("Step1 completed.", Logger::NOTICE); // handled by DebugLogger and EmailLogger $l->message("An error has occurred.", Logger::ERR); // handled by all three Loggers }}new ChainOfResponsibilityExample();?>
関連項目

Interception パターン


Interceptor パターン

Single responsibility 原則(英語)

外部リンク

Article " ⇒
The Chain of Responsibility pattern's pitfalls and improvements" by Michael Xinsheng Huang(英語)

Article " ⇒Follow the Chain of Responsibility" by David Geary(英語)

Article " ⇒Pattern Summaries: Chain of Responsibility" by Mark Grand

CoR overview(英語)

Behavioral Patterns - Chain of Responsibility Pattern(英語)

Descriptions from Portland Pattern Repository(英語)

Apache Jakarta Commons Chain(英語)










デザインパターン
GoFによる23種のパターン

生成に関するパターン

Abstract factory

Builder

Factory method

Prototype

Singleton

構造に関するパターン
Adapter

Bridge

Composite

Decorator

Facade

Flyweight

Proxy

振る舞いに関するパターン
Chain of responsibility

Command

Interpreter

Iterator

Mediator

Memento

Observer

State

Strategy

Template method

Visitor


並行性に関するパターン
Active object(英語版)

Balking(英語版)

Double-checked locking(英語版)

Event-based asynchronous(英語版)

Guarded suspension(英語版)

Join(英語版)

ロック

モニタ

Proactor(英語版)

Reactor(英語版)

Readers?writer lock(英語版)

Scheduler(英語版)

Thread pool(英語版)

スレッド局所記憶

アーキテクチャに関するパターン
Front Controller(英語版)

Interceptor(英語版)

MVC

MVVM

多層アーキテクチャ

Specification(英語版)

出版-購読型モデル

Naked objects(英語版)

Service Locator(英語版)

Active Record

Identity map(英語版)

Data Access Object

Data Transfer Object

その他のパターン
依存性の注入 (DI)

遅延読み込み

モックオブジェクト

Null object(英語版)

Object pool(英語版)

Servant(英語版)

Type tunnel(英語版)

関連する人々
ギャング・オブ・フォー

エーリヒ・ガンマ


次ページ
記事の検索
おまかせリスト
▼オプションを表示
ブックマーク登録
mixiチェック!
Twitterに投稿
オプション/リンク一覧
話題のニュース
列車運行情報
暇つぶしWikipedia

Size:15 KB
出典: フリー百科事典『ウィキペディア(Wikipedia)
担当:undef