我有GPS读取器类,可从GPS接收器传递坐标。显然,这可以在具有真实接收器的机器上使用。现在,我创建了一个模型类,它随机地给我坐标,这样我就可以启动我的应用程序,看看是否一切正常,而不必将其部署到另一台机器上。

现在是这样的结构:

class AbstractGPSReader {
}

class RealGPSReader extends AbstractGPSReader {
}

class FakeGPSReader extends AbstractGPSReader {
}

class SomeOtherClass {
    private AbstractGPSReader gpsReader = new RealGPSReader();
}


为了能够测试应用程序,我必须替换

new RealGPSReader()




new FakeGPSReader()


有没有更优雅的方式?
我可以阻止某人在生产中使用此类吗?

最佳答案

您应该使用dependency injection。这很简单:应该为类提供其依赖项的实例,而不是自己创建依赖项。

例如:

class SomeOtherClass {
    private final AbstractGPSReader gpsReader = new RealGPSReader();
}


成为:

class SomeOtherClass {
    private final AbstractGPSReader gpsReader;
    public SomeOtherClass(AbstractGPSReader gpsReader) {
        this.gpsReader = gpsReader;
    }
}


这样做的好处是,现在SomeOtherClass仅与AbstractGPSReader耦合,而之前它仅与AbstractGPSReaderRealGPSReader耦合。

在编写单元测试时,这是一个巨大的好处,因为现在该类可由未经修改的测试套件使用:

void testSomeOtherClass() {
    SomeOtherClass someOtherClass = new SomeOtherClass(new FakeGPSReader());
    someOtherClass.someMethod();
    // etc...
}


有一些框架可以帮助您自动化依赖项的注入,但是我建议您推迟使用这些框架以保持代码的简单性。



顺便说一句,您应该尝试围绕接口而不是抽象类构建API。

09-11 19:18