呼び出し元のクラスの変数にアクセスするクラス?

Scalaであるプログラムを作成しています。あるアルゴリズムを利用したネットワーク処理を行なうプログラムです。
内部状態や変数を持つクラスAが存在しており、(定期的に外部からの命令で)ある条件でその変数などが変更されるのですが、可読性の向上と処理の簡単のため、処理を独立させるべくStrategy Patternを適用しようと思います。
クラスAのある処理判断を別のクラスBにさせるという意味です。
しかしながらStrategyクラスから処理元のクラス変数にアクセスするにはクラスのインスタンスを引数として渡すか、Singletonとして呼び出すしか方法がないように思われます。

具体的に申しますと、外部のノードの死活などを判定し、とるべき行動(そのノードを切る、等)を判断させるのですが、その「とるべき行動」がすなわち「クラス変数への作用」です。
したがって外部のクラスに独立させるとクラス変数へのアクセスが煩雑なものになる状況です。

スマートな解決法はないのでしょうか。元クラスに全ての判断と処理を書くべきなのでしょうか。

よろしくお願いいたします。

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2013/07/11 22:57:28
  • 終了:2013/07/18 23:00:06

回答(1件)

id:a-kuma3 No.1

a-kuma3回答回数4465ベストアンサー獲得回数18422013/07/17 12:23:32

ポイント100pt

いまいち、状況が理解できてないので、的を外してたらごめんなさい。


Strategy パターンは、実行するときにアルゴリズムを外部で選択できる、というところが肝ですが、切り替えたくなるアルゴリズムというのは、何になるのでしょう?
ノードの状況判定(死活など)、それとも、採るべき行動(ノードの切断など)でしょうか? それとも、両方?

Strategy の Context であるクラスAというのは、何を表しているのでしょう。
ノードそのものではないですよね?
Strategy であるクラスBは、ノードの状態がアクセスできて、ノードに対して操作ができれば、十分なように読めますが、違いますか?

雰囲気は、こんな感じでしょうか?
f:id:a-kuma3:20130717114537j:image
Strategy には、以下のメソッド。

  • isNeedAction (Node a) : boolean ―― Node の状態を判定
  • doAction (Node a) : void ―― Node に対する行動

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 パターンは、あるクラスのインスタンスが、そのドメインでひとつだけ存在できる場合に、そのインスタンスの初期化とアクセス方法を定めるものです。
何かを受け渡したいから、という目的で導入すると、いずれ破たんします。

id:Windymelt

ご返答ありがとうございます.

>切り替えたくなるアルゴリズムというのは、何になるのでしょう?
>ノードの状況判定(死活など)、それとも、採るべき行動(ノードの切断など)でしょうか? 

ファクトリに各種の条件を渡し,採るべき行動のStrategyを生産しています.

>Strategy の Context であるクラスAというのは、何を表しているのでしょう。
>ノードそのものではないですよね?
>Strategy であるクラスBは、ノードの状態がアクセスできて、ノードに対して操作ができれば、十分なように読めますが、違いますか?

乱筆で分かりにくかったと思います.失礼しました.
クラスAというのは,まさしくノードです.AのメソッドとしてStrategyであるBのファクトリが実装されています.(ファクトリが独立してない)
StrategyであるBがAの変数に干渉するという性質上,直接内部にアクセスすると結合度が悪くなると思い,実際のAの変数の変更と,Bで実施されるべき処理を分離したかったのです.(Bで処理の内容だけ作成し,Aで実行してA内部を変更する)

>必要な情報を詰め込んだ Transfer Object
自分でもよく考えた結果,この方式が一番有用だと考え,Stateモナドを利用した処理を採択することにしました.
クラスAがStrategyであるBを生成し,BのdoActionがStateモナドを生成し,これをAに実行させることでうまくいきました.

>Singleton パターンは、あるクラスのインスタンスが、そのドメインでひとつだけ存在できる場合に、そのインスタンスの初期化とアクセス方法を定めるものです。
>何かを受け渡したいから、という目的で導入すると、いずれ破たんします。

納得いたしました.ありがとうございます.


ご回答とは別にこちらでほぼ解決してしまうような形になってしまいましたが,非常に有用なご回答を頂きました.重ねて御礼いたします.
できたコードを公開したかったのですが,あいにく作成途上であるため公開には至りませんでした.
コードはいつかの機会に公開したいと思います.その際はお報せしたいと思います.

2013/07/23 06:18:54

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません