【问题标题】:Dependency injection as a rule?依赖注入作为一项规则?
【发布时间】:2013-07-30 16:57:39
【问题描述】:

我正在尝试为扑克手历史编写一个解析器系统。有些会使用正则表达式,有些会使用 XML,等等......

目前我有这个:

abstract class Parser {

    abstract protected GameContext findGameContext();

    public void parse() {
      GameContext gameContext = findGameContext();
    }    
}

还有:

class RegexParser {
    protected GameContext findGameContext() {
        // find game context by using some regex...
    }
}

我对此很满意。如果我想要另一种解析器,我将 Parser 子类化并实现抽象方法。
但是,我知道我可以使用依赖注入来做同样的事情。
像这样的:

class Parser {

    private IDataType<GameContext> gameContextFinder;

    public setGameContextFinder(IDataTypeFinder<GameContext> finder) { this... = ... }

    public parse() {
        GameContext gameContext = this.GameContextFinder.find();
        ...
    }

地点:

interface IDataTypeFinder<T> {
    public T find();
}

class GameContextFinder implements IDataTypeFinder {
    public GameContext find() {
        // some regex...
    }
}

还有:

class RegexParser extends Parser {

    public RegexParser() {
        this.setGameContextFinder( new GameContextFinder() );
    }                                        
}

你怎么看这两种方式? 到目前为止,我发现 DI 对单元测试很有用。 但是抽象继承感觉更“自然”……

【问题讨论】:

  • 我认为第一种方法更好更干净。第一种方法在这里也是可单元测试的。第一种方法不需要依赖注入。您可以轻松地模拟解析器和上下文。

标签: inheritance dependency-injection abstract-class


【解决方案1】:

我不确定我是否理解“游戏上下文”包含的内容,也不明白为什么解析器需要一个。但是,我会让解析器之外的东西找到游戏上下文并将其注入到基本解析器类中。每个子类解析器都可以根据需要使用该上下文。

我更喜欢保留几个作为解析器的类,但它们都是 Parser 主类的子类,或者都实现了 Parser 接口。 (在接口情况下,我们通常使用BaseParserParserImpl 类,因为我们需要一个根类。)

然后,在你使用解析器的地方,你会保留一个保存它的变量:

public UsingParserClass {
    private Parser theParser;

    public setParser(Parser val) { theParser = val;}
}

它会有更多的方法来做实际的工作。

然后,您使用 setter 将所需的子类注入到 UsingParserClass 的实例中。不同的依赖注入框架以不同的方式做到这一点。或者你可以使用你的代码来做。

您还可以找到游戏上下文并将其从同一位置注入解析器。

... some setup code somewhere ...

myUsingParserClass.setParser(new RegexParser());
myUsingParserClass.getParser().setGameContext(gameContextFinder.find());

【讨论】:

  • 感谢您的回答。 GameContext 是一个枚举,它可以是解析器想要从手牌历史中提取的与游戏相关的任何信息(变体、限制、nb 玩家......)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-01
  • 2021-02-24
  • 1970-01-01
  • 2020-12-20
  • 2020-03-14
  • 1970-01-01
  • 2020-03-14
相关资源
最近更新 更多