責任デザインパターン連鎖
責任パターンの連鎖は、デザインパターンについてのG . O . Fブックからの行動パターンです、このパターンは非常にあなたがそのレシーバーから送付者を切り離す必要があるとき、そして、各々のレシーバーが果たすいくつかの責任があるとき、役に立ちます.
例えば、メールサーバーを持っているとして、スパム、ファン、ビジネスを特定する方法を確認して、メールを通常のメールから文句を言い、このメールをメールサーバーに実装するように求められます. スパムは無視する必要があります. ファンのメールは会社のCEOに直接転送する必要があります. ビジネスメールは、企業の電子メールに転送する必要があります. 苦情メールは、消費者部門に向けられる必要があります. 今、我々は単に我々の論理のチェックをして、必要条件を達成するならば、我々は単に入れられることができます、しかし、それは問題です
理由 新しい規則を追加する必要があるときはいつでも、我々は我々の機能を変えるでしょう. 私たちはまた、その機能がその多くのことをしているように、単一の責任原則を破ります
独自. より良いアプローチは、それぞれの責任のために異なったハンドラー、すなわちスパム、ファンをフィルタリングして、それからいくつかの方法を一緒に結合します.これはCORが私たちを助けるのです.このパターンの実装を見てみましょう.
こちらです.
実装のために抽象クラスの代わりに機能インターフェースを選びました
さて、このインターフェイスの具体的な実装の一つを見てみましょう
同様に、そのプロセスを処理するチェーン内の他のフィルタも存在する
このチェーンを生成し、あなたを与えるいくつかの戦略や工場
これはあなたのコードの他のチェーンの場合よりもはるかにクリーナーな解決策であり、また
この場合のハンドラ/フィルタ(例えば)、例えば、チェーンを初期化するために別々のクラスがあるならば
チェーンからいつでも触れずに
また、すべてのフィルタ論理はそれ自身のクラスに存在します.
ソフトウェア世界のすべてのものと同様に、このパターンはまた、魔法の弾丸ではなく、コンズと来る チェーンが非常に長いなら、問題がどこにあるかをデバッグして、確認するのは難しいです. ハンドラの非常に長いチェーンでは、呼び出しスタックも同様に成長し、パフォーマンスの問題につながる可能性があります. 重複を避けることができますが、ハンドラの間でコードを複製することができます. 要求オブジェクトがすべてのハンドラで実行されなければならないという保証を必要としないとき、それを使用してください
デコレータパターン. 複数のハンドラがリクエストオブジェクトを処理することができなければならないときに使用し、送信者にどんなアイデアを持っていても構わない
複数のハンドラについて クライアントが要求を実行するハンドラを知らなければならないとき、それを使用しないでください.
CORデザインパターンは、そのレシーバーから送付者を切り離すのを助けます
それを知っている送付者なしで複数のハンドラまたはレシーバーは、それから、送付者のコードに触れることなくレシーバーを取り除くか、加えるために柔軟性を与えます.
あなたは私の上で同じを読むかもしれませんpersonal blog .
Chain of Responsibility pattern wikipedia Head First Design Pattern book Source code for above example
例えば、メールサーバーを持っているとして、スパム、ファン、ビジネスを特定する方法を確認して、メールを通常のメールから文句を言い、このメールをメールサーバーに実装するように求められます.
理由
独自.
Let's refer the Chain of responsibility pattern with COR now on wards.
こちらです.
MailFilter
抽象インターフェイスfilter
次に、具体的なクラスごとに実装されます.SpamFilter
, FanFilter
, したがって、各フィルタは、フィルタロジックの独自の実装を提供します.MailServer
クラスは、それに割り当てられたハンドラーにメールオブジェクトを送る送付者クラスです.そして、実際の実装で、それが1つ以上のハンドラがあるかどうか、そして、それがどのハンドラを相互作用しているかどうか知りません.実装
実装のために抽象クラスの代わりに機能インターフェースを選びました
MailHandler
一つは抽象的な方法しかないからです.
@FunctionalInterface
public interface MailFilter {
default MailFilter appendNext(MailFilter next) {
return mail -> {
filter(mail);
next.filter(mail);
};
}
void filter(Mail mail);
}
注意appendNext
関数は、同じインタフェース(呼び出し元)を呼び出し元に返します.filter
メソッド(具体的なクラスである)next.filter(mail)
チェーンの次のハンドラーのメソッド.さて、このインターフェイスの具体的な実装の一つを見てみましょう
SpamFilter
class SpamFilter implements MailFilter{
private final List<String> allowedMails = Arrays.asList(
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]"
);
@Override
public void filter(Mail mail) {
if(isSpam(mail)) {
System.out.println("Ignoring spam mail");
}
}
private boolean isSpam(Mail mail) {
return !allowedMails.contains(mail.from());
}
}
ご覧の通りSpamFilter
クラスはMailFilter
インターフェースなので、filter
次に、Mail
オブジェクトをフィルタリングすることができます.The filtering logic in above example is just for demo purpose, please don't use it in production :)
同様に、そのプロセスを処理するチェーン内の他のフィルタも存在する
Mail
論理/条件が通るならば、オブジェクトとそれに取り組む.どのようにそれが送付者/クライアントによって使われているか見ましょう.class MailServer {
private final MailFilter filter;
public MailServer() {
filter = init();
}
private MailFilter init() {
return new SpamFilter()
.appendNext(new FanFilter())
.appendNext(new BusinessFilter());
}
public void process(List<Mail> mails) {
mails.forEach(filter::filter);
}
}
ここではデモの目的のために私は同じクラスのチェーンを定義するために選択しているが、実際のシナリオでは、する必要がありますこのチェーンを生成し、あなたを与えるいくつかの戦略や工場
filter
あなたのコードで扱うオブジェクト.ここでは、私たちはprocess
メールのリストを受信して1つずつ処理する方法.これはあなたのコードの他のチェーンの場合よりもはるかにクリーナーな解決策であり、また
この場合のハンドラ/フィルタ(例えば)、例えば、チェーンを初期化するために別々のクラスがあるならば
MailServer
クラスはメールオブジェクトがどれくらいのフィルタを通過するかさえ知らないでしょうチェーンからいつでも触れずに
MailServer
クラス.また、すべてのフィルタ論理はそれ自身のクラスに存在します.
欠点
ソフトウェア世界のすべてのものと同様に、このパターンはまた、魔法の弾丸ではなく、コンズと来る
考慮すべき点
デコレータパターン.
複数のハンドラについて
結論
CORデザインパターンは、そのレシーバーから送付者を切り離すのを助けます
それを知っている送付者なしで複数のハンドラまたはレシーバーは、それから、送付者のコードに触れることなくレシーバーを取り除くか、加えるために柔軟性を与えます.
javax.servlet.Filter
APIはJava Worldで実装されているパターンの良い例です.このパターンの別の良いケースはログオンしています.wikipedia 実装でこの例を挙げてください.しかし、開発者として、我々はこれらを意識しなければならないように、Corパターンもその欠点を持ちます.あなたは私の上で同じを読むかもしれませんpersonal blog .
参考文献
Reference
この問題について(責任デザインパターン連鎖), 我々は、より多くの情報をここで見つけました https://dev.to/novicedev7291/chain-of-responsibility-design-pattern-35p1テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol