私は現在、各クラスが別の構造の対応するレベルからオブジェクトを返すことができるように、メソッドの戻り値の型がオープンジェネリックとして残されている継承構造を持っています。たとえば、ProduceVehicle TVehicle ができる TVehicle:Vehicle の VehicleFactory があるとします。TVehicle:Car の CarFactory:VehicleFactory もあります。
Car は Vehicle から継承するため、これはすべて有効であり、CarFactory は Car を生成する必要があり、Vehicle ファクトリはあらゆる種類の車両を生成できることを知ることができます。私が遭遇した問題は、VehicleFactory が Ford によって実行されているときは CarFactory としてインスタンス化する方法が必要なことですが、Wave Runner によって実行されているときは BoatFactory としてインスタンス化する方法が必要です。
これは、VehicleFactory の機能に一致するインターフェイスを作成し、IVehicleFactory を返す MakeFactory メソッドを作成することで実現できると考えました (非ジェネリックに車両を返します)。CarFactory は車両である車を返すため、インターフェイスを満たし、すべてが正しいはずです。予期しない問題は、TVehicle が Vehicle でなければならないという事実にもかかわらず、VehicleFactory が TVehicle が Vehicle であるとして閉じられているインターフェイスに適合しないことです。
これがなぜなのか、またはこの制限を回避する別の方法があるのか 誰かが知っていますか? この制限を直接回避する方法がない場合、機能の共有セットを使用して、より具体的なクラスの 2 つ以上のセットの 1 つとして常にインスタンス化されるようにする代替方法はありますか。(Vehicle は共有レイヤーで、Car と Boat はコンテキスト固有のレイヤーです。)
class Vehicle
{
}
class Car : Vehicle
{
}
interface IVehicleFactory
{
Vehicle ProduceVehicle();
}
class VehicleFactory<TVehicle> : IVehicleFactory
where TVehicle:Vehicle
{
public virtual TVehicle ProduceVehicle()
{
}
}
class CarFactory<TVehicle> : VehicleFactory<TVehicle>
where TVehicle : Car
{
public override TVehicle ProduceVehicle()
{
}
}
そしてそれを使ったコード
static IVehicleFactory CreateVehicleFactory()
{
if(somecondition)
{
Return new CarFactory<Car>();
}
else
{
Return new BoatFactory<Boat>();
}
}
問題を明確にするために、さらに詳細を追加します。
ファクトリという用語の使用は、ファクトリ パターンを意味するものではありません。これは、実際には「車両」を取得するリポジトリです。車両のタイプは、共通の共有基本コードを持つライブラリのアプリケーション固有バージョンです。Car および Boat の各アプリケーションのリポジトリは、同じ取得に対して異なるロジックを持つ場合があり、オブジェクトの Car または Boat バリアントのフィールドに依存する場合があります。車両レベルの共有コードがアプリケーション固有のオーバーライドされた機能を適切に使用するように、現在のアプリケーションのコンテキストを見て適切なリポジトリ (BoatFactory または CarFactory) を返すことができるファクトリを構築する方法が必要です。