他の回答が、あなたがそれを引き起こしたときに問題に回答しました。しかし、私はあなたがこのファクトリメソッドで達成しようとしていることを理解するために一歩前進したいと思います。このファクトリは基本的にデータ型のマップをIDataSource
のパラメータに提供します。 Dependency injectionは、これがデータ型と実装の小さな既知のセットであるため(例のように)、より適切なパターンになる可能性があります。 IDataSource<Widget>
とIDataSource<Gadget>
を実装MysqlGadgetDataSource
を実装していMongoWidgetDataSource
:
あなたはモンゴ内のすべてのWidgets
が、MySQLのすべてのGadgets
を格納したいとしましょう、あなたは、2つのクラスを持っているかもしれません。
データコンシューマ内にMyFactory.getDataSource(Widget.class)
のようなファクトリメソッド呼び出しをハードコーディングする代わりに、適切なIDataSource
依存関係を挿入します。私たちはMyService
を持っていて、ウィジェット(mongoに格納されています)で何かをしているかもしれません。あなたが提案したように、工場を使用すると、次のようになります。
public class MyService {
public void doSomething() {
String value = MyFactory.getDataSource(Widget.class).getSomething();
// do something with data returned from the source
}
}
代わりに、あなたがサービスにコンストラクタ引数として適切なデータソースを挿入する必要があります
public class MyService {
private final IDataSource<Widget> widgetDataSource;
public MyService(IDataSource<Widget> widgetDataSource) {
this.widgetDataSource = widgetDataSource;
}
public void doSomething() {
String value = widgetDataSource.getSomething();
// now do something with data returned from the source
}
}
これはあなたを作るの付加的な利点を持っていますより再利用可能で単体テストが容易なコード(モックの依存関係)。
次に、MyService
をインスタンス化すると、データソースを接続することもできます。多くのプロジェクトでは、これを簡単にするために依存性注入フレームワーク(Guiceなど)を使用していますが、厳密な要件ではありません。個人的には、実際のサイズや期間を持たないプロジェクトでは決して作業しません。
public static void main(String[] args) {
IDataSource<Widget> widgetDataSource = new MongoWidgetDataSource();
IDataSource<Gadget> gadgetDataSource = new MysqlGadgetDataSource();
MyService service = new MyService(widgetDataSource, gadgetDataSource);
service.doSomething();
}
Guiceのでは、あなたはこのように、これらのデータソースを配線します:あなたはDIフレームワークを使用しない場合は、呼び出し元のサービスを作成するときに
は、あなただけの依存関係をインスタンス化
public class DataSourceModule extends AbstractModule {
@Override
protected void configure() {
bind(new TypeLiteral<IDataSource<Widget>>() {}).to(MongoWidgetDataSource.class);
bind(new TypeLiteral<IDataSource<Gadget>>() {}).to(MysqlGadgetDataSource.class);
}
}
依存関係の逆転は、問題について考えるのとは少し違う方法ですが、デカップルされた、再利用可能でテスト可能なコードベースにつながります。
public static <T> IDataSource<T> getDataSource(MyData dataType) {
System.out.println("Make MyDataSource");
return (IDataSource<T>) new MyDataSource();
}
public static <T> IDataSource<T> getDataSource(MyOtherData dataType) {
System.out.println("Make MyOtherDataSource");
return (IDataSource<T>) new MyOtherDataSource();
}
public void test() {
IDataSource<MyData> myDataSource = getDataSource((MyData) null);
IDataSource<MyOtherData> myOtherDataSource = getDataSource((MyOtherData) null);
}
私が持っているようにあなたが空のアーキタイプではなく、キャストnull
を作成することを好むかもしれませんが、私は、これは実行可能な技術であると思う:
これはあなたの質問に答えませんが、 'equals'の代わりに' Class'esに '=='を安全に使うことができます。 – Boann