다른 답변으로 인해 문제가 해결되었습니다. 그러나 나는이 공장 방법으로 무엇을 성취하려고 하는지를 이해하기 위해 한 발 뒤로 물러서 고 싶다. 이 팩토리는 기본적으로 IDataSource
매개 변수에 데이터 유형의 맵을 제공합니다. Dependency injection은 더 잘 알려진 패턴 일 수 있습니다.이 패턴은 잘 알려진 작은 데이터 유형 및 구현 집합이므로 (예제에서와 같이) IDataSource<Widget>
를 구현하는 MongoWidgetDataSource
및 IDataSource<Gadget>
를 구현하는 MysqlGadgetDataSource
:
의 당신이 MySQL의 모든 몽고에서 Widgets
하지만 모든 Gadgets
를 저장할 가정 해 봅시다
, 당신은 두 개의 클래스가있을 수 있습니다.
데이터 소비자 내부에서 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