Scalaであるプログラムを作成しています。あるアルゴリズムを利用したネットワーク処理を行なうプログラムです。
内部状態や変数を持つクラスAが存在しており、(定期的に外部からの命令で)ある条件でその変数などが変更されるのですが、可読性の向上と処理の簡単のため、処理を独立させるべくStrategy Patternを適用しようと思います。
クラスAのある処理判断を別のクラスBにさせるという意味です。
しかしながらStrategyクラスから処理元のクラス変数にアクセスするにはクラスのインスタンスを引数として渡すか、Singletonとして呼び出すしか方法がないように思われます。
具体的に申しますと、外部のノードの死活などを判定し、とるべき行動(そのノードを切る、等)を判断させるのですが、その「とるべき行動」がすなわち「クラス変数への作用」です。
したがって外部のクラスに独立させるとクラス変数へのアクセスが煩雑なものになる状況です。
スマートな解決法はないのでしょうか。元クラスに全ての判断と処理を書くべきなのでしょうか。
よろしくお願いいたします。
いまいち、状況が理解できてないので、的を外してたらごめんなさい。
Strategy パターンは、実行するときにアルゴリズムを外部で選択できる、というところが肝ですが、切り替えたくなるアルゴリズムというのは、何になるのでしょう?
ノードの状況判定(死活など)、それとも、採るべき行動(ノードの切断など)でしょうか? それとも、両方?
Strategy の Context であるクラスAというのは、何を表しているのでしょう。
ノードそのものではないですよね?
Strategy であるクラスBは、ノードの状態がアクセスできて、ノードに対して操作ができれば、十分なように読めますが、違いますか?
雰囲気は、こんな感じでしょうか?
Strategy には、以下のメソッド。
Strategy#isNeedAction() や、Strategy#doAction() では、Node に対するメッセージングは、必要に応じて、ということになると思います。
その「必要に応じて」が煩雑なのであれば、Strategy に既定の実装があって、そこで手順を実装するのが、ひとつの解決策だと思います。
Strategy のためだけに、Context や Node に getter メソッドを作らなくてはいけないのが面倒だ、ということであれば、ひとつの解決方法は、スコープに応じて、Context や Node が処理を隠ぺいしたメソッドを提供することになると思います。
Node にも複数の実装があって、それに対する呼び出しが煩雑だ、ということであれば、Node の抽象化が足りないような気がします。
実は判定のために必要な情報は、Node だけではないのだ、ということであれば、Strategy のメソッドに Context を渡すか、必要な情報を詰め込んだ Transfer Object を作ることになるんだと思います。
不要な getter を作るのが嫌、ということに対する、もうひとつの解決方法が DTO になると思います。
もし、切り替えるべきアルゴリズムというものが無い、ということであれば、それは Stratery パターンではありません。
ただの「委譲」。
「アルゴリズムの切り替え」という目的があれば、委譲元へのアクセスの煩雑さは、その目的で得られるメリットとのトレードオフになります(Strategy パターンを採択する)。
もし、切り替えという目的が無ければ、ただのロジックの分離なわけで、それが煩雑なメッセージングを必要としているのであれば、「可読性の向上と処理の簡単のため」が実現できているかどうかも、怪しいです。
本筋ではないですが、
しかしながらStrategyクラスから処理元のクラス変数にアクセスするには(省略)、Singletonとして呼び出すしか方法がないように思われます。
Singleton パターンは、あるクラスのインスタンスが、そのドメインでひとつだけ存在できる場合に、そのインスタンスの初期化とアクセス方法を定めるものです。
何かを受け渡したいから、という目的で導入すると、いずれ破たんします。