特性T
があるとします。以下を達成するための最良の方法は何ですか:T
の実装を書き込んScalaでのファクトリの実装を簡潔に行う方法
- みんなが
T
のパラメータなしの初期化を可能にする可能性を提供することを余儀なくされなければならない、すなわち、我々は、おそらくの実装を強制する必要があります設定可能な工場。 - 実際の初期化パラメータ(特定の実装
A
のT
)にのみ依存するすべてのロジック/データは、一元的に処理/格納する必要がありますが、工場とA
の両方で使用可能にする必要があります。
私は(約)これを実現するために見る最も簡単な/簡潔な方法は、この工場に工場やリンクT
のための形質を追加するには、次のようになります。
trait T {
val factory: TFactory
}
trait TFactory {
def build(): T
val description: String // example for logic/data that only depend on the parameters
}
// example implementation:
class A(val factory: AFactory, paramA: Int, paramB: Int, paramC: Int) extends T
class AFactory(paramA: Int, paramB: Int, paramC: Int) extends TFactory {
def build = new A(this, paramA, paramB, paramC)
val description = f"$paramA $paramB $paramC"
}
明らかにこれは実際には「強制しません(別の実装が利用可能である限り)ファクトリの実装であり、明らかにA
のインスタンス化を生成して、「間違った」TFactory
にリンクすることが可能です。私がこのアプローチについて気に入らないのは、初期化パラメータの繰り返しです。私はしばしば、別のクラスAParams
を作成して、新しいパラメータを追加しやすくするために、すべてのパラメータを再度ラップします。したがって、私は3つのクラスで終わります。imhoは、この単純な問題のための多くの定型文です。
私の質問は、同じ主な目標を達成する(しかし完全に)異なるアプローチがあるかどうかですが、より簡潔ですか?
間違いなく、面白いアイデア、ありがとう!私が見る実用的な問題は、工場が軽量であるという概念を直感的に失うことですが、実際には 'T'の実装はかなり重いかもしれません。多くの場合、実際の 'A'の構築には大量の初期化が必要なため、かなりのメモリフットプリントを持つ' A'のインスタンスが生成されます。おそらく、 'A'のインスタンスで終わることはよくあります。これは' T'という実際の意味で実際には使用しませんが、単に不必要なオーバーヘッドを持つファクトリです。しかし、おそらくそれは簡素化のために支払う価格です。 – bluenote10
あなたの工場でTのコンストラクタパラメータを使う必要があるようですので、Tのインスタンスを持たずにそのようなファクトリをどのように持つことができないのか分かりません。ファクトリーとTのサブクラスのコンストラクターの両方に提供できるクラスです。 –
デザインの観点から純粋に言えば、Tを構築する唯一の方法ではない場合、そのようなファクトリを実行する必要はないと思います。おそらく、関数を使うことができるいくつかのメソッドがあります: 'MakeTsAndDoUsefulThings(factory:()=> T)'。 私はあなたのクライアントのコードとして 'SonOfT'を作成し、その関数を使用する必要があることを知りたい場合は、おそらく私のコンパニオンオブジェクトに' SonOfT'のためのファクトリを組み込み、 'MakeTsAndDoUsefulThingsこのメソッドを使用する必要がない場合は、工場を作る必要はありませんが、これは大丈夫です。 –