你的第一步是設計依賴注入 - 避免構造函數和靜態方法,而是採取你需要的實例。看起來這些類型是Provider<DeviceEntity>
,DevicesAccessor
和DeviceTypesAccessor
。
Provider
是a very simple Guice interface,它通過單個無參數方法get()
提供任何類的實例在其類型參數中。如果你有綁定Foo
,Guice自動知道如何綁定Provider<Foo>
。如果你的實例很貴,或者如果你在servlet的整個生命週期中需要多於一個的話(如你所做的那樣),這是非常有用的。
重構依賴注入後,你的類將是這樣的:
public class AddDevice extends JsonServlet {
private static final long serialVersionUID = 1L;
private final Provider<DeviceEntity> deviceEntityProvider;
private final DevicesAccessor devicesAccessor;
private final DeviceTypesAccessor deviceTypesAccessor;
@Inject
public AddDevice(Provider<DeviceEntity> deviceEntityProvider,
DevicesAccessor devicesAccessor,
DeviceTypesAccessor deviceTypesAccessor>) {
this.deviceEntityProvider = deviceEntityProvider;
this.devicesAccessor = devicesAccessor;
this.deviceTypesAccessor = deviceTypesAccessor;
}
@Override
protected void doGet(final JsonServletRequest request,
final JsonServletResponse response) throws ServletException,
IOException {
try {
final DeviceEntity device = deviceEntityProvider.get();
device.type = deviceTypesAccessor.queryForId(
Integer.valueOf(request.getParameter(DeviceTypeEntity._ID)));
device.sn = request.getParameter(DeviceEntity._SN)
device.status = Long.valueOf(0);
devicesAccessor.create(device);
} catch (final SQLException e) {
throw new ServletException("device already exists");
}
}
}
在這一點上,它是非常容易通過傳遞在跟蹤它返回實例的提供者寫一個測試,沿與模擬DevicesAccessor和模擬DeviceTypesAccessor。 (我建議Mockito。)如果您編寫自己的提供程序界面並刪除@Inject
,則甚至不需要使用Guice;在測試中,你可以繼續使用該構造,而是希望滿足的Java EE與像一個構造函數:
public AddDevice() {
this(new NewDeviceEntityProvider(),
FleetManagerDatabaseHelper.deviceTypesAccessor(),
FleetManagerDatabaseHelper.devicesAccessor());
}
private class NewDeviceEntityProvider implements Provider<DeviceEntity> {
@Override public DeviceEntity get() {
return new DeviceEntity();
}
}
但是,如果你想使用吉斯移除樣板,只寫了吉斯Module
。您的模塊需要將DeviceTypesAccessor和DevicesAccessor綁定到FleetManagerDatabaseHelper將返回的實例; Guice會看到DeviceEntity
有一個無參數構造函數,並且能夠自動注入DeviceEntity
和Provider<DeviceEntity>
。 (評論,如果你想我擴大Module
看起來像什麼。)
希望這有助於!
看起來像很多樣板代碼 –
@Adrian大多數代碼是你的方法;唯一的樣板是頂部的一系列字段,以及填充它們的構造函數。這是一些樣板,是的,但從長遠來看可以節省您的可測試性和可配置性。另外,儘管我更喜歡「構造函數注入」,但您甚至可以直接用'@ Inject'標註注入的字段來跳過該過程。 –