Spring ServiceLocator还是纯工厂模式? [英] Spring ServiceLocator or pure factory pattern?

查看:101
本文介绍了Spring ServiceLocator还是纯工厂模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的依赖项的99%通过@Autowired Spring注释使用DI模式进行管理。

99% of my dependency is manage with DI pattern via @Autowired Spring annotation.

然而在特定情况下,我无法确定要使用哪种实现直到运行时。

Nevertheless in a particular scenario, I can't determine which implementation to be used until run-time.

最着名的情况是解析器的多重实现。

The most known case, is the multiple implementation of parsers.

第一个解决方案是使用多个@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;

    ...     
}

但如果我有大量的实现是不可接受的。

But if I have a large number of implementation that can be not acceptable.

第二个解决方案是使用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");
    }
}

这种做法对我来说似乎是正确的,但与第三种解决方案?

This way to do seems right to me but compared with the third solution?

第三种解决方案是使用纯工厂模式并注入它。

@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");
    }
}

如果你有以前解决方案的pro / con,或者甚至更好地解决我的问题?

If you have pro/con for the previous solutions, or even better solution for my problem?

PS:这是伪代码我可能会遗漏一些小事:)

PS: it's pseudo code I may miss some small things :)

推荐答案

作为一个选项,你可以使用列表注入:

As an option you can use list injection:

public class SomeService {

    @Autowired 
    private List<Parser> parsers;

    public doSomethingWithParser(...) {
        ...
        Parser parser = getParser(JsonParser.class);
        parser.parse(...);
        ...
    }

    private Parser getParser(Class<Parser> targetClass) {
        Parser result = null;
        for(Parser parser : parsers) {
            if(parser.getClass().equals(targetClass)){
                result = parser;
            }
        }
        return transformer;
    }

}

更好的是,你可以添加 Parser.isCompatibleWith(SomeInput输入)简化paser检测代码的方法。

Even better, you can add Parser.isCompatibleWith(SomeInput input) method to simplify paser detection code.

这篇关于Spring ServiceLocator还是纯工厂模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆