2017-02-11 5 views
0

を実装するために、自己のタイプを使用。戦略実装は、それらの戦略を使用するクラスの保護された/パブリックなメンバーにアクセスする必要があり、戦略を使用するクラスは戦略のパブリックメンバーにアクセスする必要があります。スカラ:私は状態を管理して、私が持っているクラスのための戦略パターンを実装しようとしてるの戦略パターン

私は本当にあたりの戦略異なるトップレベルのクラスを作成せずにこれを行う方法を見つけ出すことはできませんを除いて、この作業を持っています。次に例を示します。

class BranchState(a: String, b: Int) extends ABranchState(a, b) with QueuedStrat 

class ABranchState(a: String, b: Int) { 
    this: ChainingStrategy => 
    .... lots of impl .... 
} 

trait ChainingStrategy { 
    self: BranchState => 
    ... headers only, no impl ... 
} 

trait QueuedStrat extends ChainingStrategy { 
    self: BranchState => 
    .... impl .... 
} 

trait AnotherStrat extends ChainingStrategy { 
    self: BranchState => 
    .... impl .... 
} 

ここでの問題は、私が使用するAnotherStratでBranchStateをインスタンス化したい場合は、私は別のクラスを作成する必要があります。私は[T <: ChainingStrategy]のようなBranchStateに型パラメーターを追加しようとしましたが、コンパイラーが(正当な理由で)私がChainingStrategyのヘッダーの実装を持たなければならないと不満を表明するため、動作しません。 「連鎖戦略を実装するいくつかのタイプは、 IE:実装されていないメソッドはありません。

たぶんそれはしかし、ちょうど全く正しい方法ではありません。どうすればこれを達成できますか?

ありがとうございました

+0

言語力学の点で面白いですが、デザインとしては複雑です。なぜ戦略は、戦略を使ってクラスについて知る必要がありますか?気分が悪い – Dici

+0

はい、私はこれを整理する他の多くの方法について考えることができます。実際には同じパターンではなく、混乱していると思われるので、ここではそれらを "戦略"と呼んではいけません。私は主にこのメカニズムを働かせることに興味があります。 – Sushisource

答えて

0

私はあなたがしようとしていることは、デザインの面では意味をなさないと思います。彼らはあなたの戦略を州のように扱っています。しかし戦略は国家の専門化または一般化ではないので、私は彼らに相続関係があるとは思わない。

さらに、Scalaでは、戦略パターンが必要ではありません。言語の機能面では、Higher-order Functions(実際にはHow Scala killed the Strategy Pattern、Alvin Alexanderを読むことをお勧めします)。

私はこれがあなたを助けてくれることを願っています!

+0

私は戦略を、状態が操作される方法の違いとして扱っています。おそらく、 "BranchState"という名前は混乱しているかもしれません。単にデータコンテナではありません。状態の変化をもたらすイベントを適用するためのパブリックAPIを公開します。私は戦略がBranchStateの非公開のメンバーにアクセスできるようにする便利な方法が必要です。私は高次関数を認識していますが、ここでそれらを使用すると、BranchStateのほぼすべてのフィールドを前後に渡すことになります。これはよりエレガントに見えました。私の問題をフレーム化するもう一つの方法は、 "別のファイルで内部クラスをどのようにするか"です。 – Sushisource

+0

私は単にサブパッケージにこのすべてを貼り付けると戦略によって操作する必要がBranchStateフィールドが ''民間[パッケージ]となって、私は、この整備士の仕事を作ることができれば、私は学ぶために興味があったされている他のオプション。 – Sushisource

+0

私は非常にきれいではないものを考えています。あなたは 'ChainStrategy'にすべてのヘッダーを実装して、' UnsupportedOperationException'をスローすることができます。それはあなたの問題を解決するだろうが、これはコンパイラから実行時にエラー検出を転送するだろうが、私はまったくファンではない。 –

関連する問題