私の依存関係の 99% は、@Autowired Spring アノテーションを介した DI パターンで管理されています。
それにもかかわらず、特定のシナリオでは、実行時までどの実装を使用するかを決定できません。
最もよく知られているケースは、パーサーの複数の実装です。
最初の解決策は、複数の @Autowired (醜いモード) を使用することです。
Interface Parser {
<T> T parse();
}
@Component("JsonParser")
class JsonParser implements Parser {
...
}
@Component("XmlParser")
class XmlParser implements Parser {
...
}
class MyService {
@Autowired
@Qualifier("XmlParser")
Parser xmlParser;
@Autowired
@Qualifier("JsonParser")
Parser jsonParser;
...
}
しかし、受け入れられない実装が多数ある場合。
2 番目の解決策は、Spring の ServiceLocator を使用することです。
interface ParserServiceLocatorFactory {
public Parser getParser(String parserName);
}
interface Parser {
<T> T parse();
}
@Component("JsonParser")
class JsonParser implements Parser {
...
}
@Component("XmlParser")
class XmlParser implements Parser {
...
}
class MyService {
@Autowired
ServiceFactory parserServiceLocatorFactory;
void exampleMethod() {
Parser xmlParser = parserServiceLocatorFactory.getParser("XmlParser");
}
}
この方法は私には正しいように思えますが、3番目のソリューションと比較して?
3 番目の解決策は、純粋なファクトリ パターンを使用して注入することです。
@Component
public ParserFactory {
Parser getParser(String parserName) {
...
}
}
interface Parser {
<T> T parse();
}
@Component("JsonParser")
class JsonParser implements Parser {
...
}
@Component("XmlParser")
class XmlParser implements Parser {
...
}
class MyService {
@Autowired
ParserFactory parserFactory
void exampleMethod() {
Parser xmlParser = parserFactory.getParser("XmlParser");
}
}
以前の解決策に賛否両論がある場合、または私の問題に対するより良い解決策がある場合は?
PS:これは疑似コードなので、小さなことを見逃す可能性があります:)