[Go言語]Chain of Responsibilityパターンを学ぼう! ~Broker Chain編~

こんにちは、KOUKIです。

この記事では、デザインパターンの一つであるChain of Responsibilityパターンについて紹介します。

個人的には、実用的というよりは頭の体操に近い内容になっていると思いますが、知っておいて損はないパターンだと思います。

前回

デザインパターンまとめ

Chain of Responsibilityパターン

chain は「鎖」、responsibility は「責任」を意味します。故に、Chain of Responsibility パターンとは、「責任」を負ったものが、「鎖」状につながれた状態をイメージさせるパターンです

前回は、インスタンスのメソッドを繋げてこのパターンを実装しました。

今回は、syncパッケージのMapを使って、Broker Chainという形式で実装したいと思います。詳しい説明は、サンプル(ロガー)を実装しつつ行いたいと思います!

main関数

以下の状態からプログラムを実装していきます。

定数の定義

ロガーのログレベルを定数で宣言します。これは、プログラムを見やすくするためです。

ログの保存場所

ログの保存場所をグローバルで宣言します。

クエリ構造体の実装

クエリ構造体を実装します。

Observerを定義

以下のインターフェースを定義します。

Observerは、観察者という意味です。これは、ログそのものだと考えてください。

本実装の最終段階では、生成するログ自体をインスタンス化します。その一つ一つをObserverとして扱います。このObserverには、Handleという一つのメソッドを持っており、ここに個別に実装したい処理を書きます。

Observableは、Observerが実行できる処理を実装します。Subscribe(ログを保存する)、UnSubscribe(ログを削除する)、Fire(ログを処理する)の3つの機能を持たせました。

Platformを実装

Observerを管理する構造体を実装します。

Platformメソッド(s)

Platformのメソッドを実装します。

Subscribe

KeyにObserver、Valueにログレベルを指定して、sync.Map保存します。

UnSubscribe

KeyにObserverを指定して、sync.Mapからデータを削除します。

Fire

sync.Mapに格納されているデータをループして、目的のログを取得します。

引数には、Queryを渡しています。これは、ログを呼び出すときに、ロガーレベルを調整する役割を担っています。

また、sync.Mapにはログのインスタンスそのものが格納されているので「key.(Observer).Handle(q)」の様にメソッドを呼び出すことができますここが本記事のポイントですね

ロガーの定義

ロガーを定義します。

ロガーのコンストラクタ

ロガーのコンストラクタを定義します。

クエリメソッドを定義

ログをセットするクエリメソッドを定義します。

ログ表示メソッド

ログを表示するメソッドを定義します。

「l.DEBUG()」などで、表示するログレベルを調整します。
このロガーはあくまでサンプルなので現場ではこんな実装はしません

Platformとロガーを繋ぐ構造体

Platformとロガーを繋ぐ構造体を定義します。

ロガー変更構造体

ロガー変更構造体を定義します。

特別なログを表示したい場合は、以下のように新しい構造体を作成します。

ロガー変更構造体のメソッド

ロガー変更構造体には、独自の処理を実装します。

Handleメソッドにクエリからメッセージを取得し、グローバル変数に保存する処理を、Reflshメソッドにsync.Mapからログを削除する処理をそれぞれ実装しました。

使ってみよう

ここまで実装したソースコードを使ってみましょう。

OKですね。logger.String()を呼び出すだけで、全てのログが出力されました。

一応、動きましたが、結構使いづらいソースコードになりましたねw

本番で実装したらチームメンバーに怒られるかもしれません^^

まとめ

今回のプログラムはちゃんと実装できているのか一抹の不安があるので、参考程度にしておいてください。。

やりたかったことは、sync.Mapのようなキャッシュにインスタンスを保存して、後から一度に実行(数珠繋ぎ)!みたいなことでしたが、改良が必要ですね^^:

でも考え方だけは、参考になると思います(ポジティブ)!

それでは、また!

Go言語まとめ

ソースコード

コメントを残す