我有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
耦合,而之前它仅与AbstractGPSReader
和RealGPSReader
耦合。在编写单元测试时,这是一个巨大的好处,因为现在该类可由未经修改的测试套件使用:
void testSomeOtherClass() {
SomeOtherClass someOtherClass = new SomeOtherClass(new FakeGPSReader());
someOtherClass.someMethod();
// etc...
}
有一些框架可以帮助您自动化依赖项的注入,但是我建议您推迟使用这些框架以保持代码的简单性。
顺便说一句,您应该尝试围绕接口而不是抽象类构建API。