我有一个 Java 项目,其中一个非常大的类被拆分成较小的类,这完全是出于可读性的原因。使用 Guice 依赖注入。
public interface FooDataService { Foo getFoo(){} }
public class FooDataServiceImpl implements FooDataService { @Override Foo getFoo(){} }
// Also BarDataService, BazDataService, and more
public interface DataService extends FooDataService, BarDataService {}
public class DataServiceImpl implements DataService {
private final FooDataService fooDataService;
private final BarDataService barDataService;
// ...
@Inject
public DataServiceImpl(FooDataService fooDataService, BarDataService barDataService) {
this.fooDataService = fooDataService;
this.barDataService = barDataService;
// ...
}
@Override Foo getFoo(){ return fooDataService.getFoo(); }
@Override Bar getBar(){ return barDataService.getBar(); }
// A very large number of methods follow.
}
// Usage
public class ApiService {
// The idea was to only inject the one dataService variable instead of injecting FooService, BarService, etc.
// There's not really place where FooDataService is used but not BarDataService, except unit tests
@Inject
private final static DataService dataService;
public void doThing() {
dataService.getFoo();
dataService.getBar();
}
}
这很好,因为它使所有 XDataService 类都相对较小。 DataServiceImpl 本身过去有 2000 多行。 但这有点令人厌烦。
是否有更好的方法来实现它,以便我们可以拥有小型的、可读性强的课程?
Lombok 的@Delegate 在这里会有帮助——但它目前只是一个实验性功能。 此注释允许您消除样板代码(对委托服务的直接调用):
public interface DataService extends FooDataService, BarDataService {}
public class DataServiceImpl implements DataService {
@Delegate(FooDataService.clas)
private final FooDataService fooDataService;
@Delegate(BarDataService.clas)
private final BarDataService barDataService;
// no more doFoo(x) { fooService.doFoo(x) }
// only the code that does delegate here.
}
如果您觉得这很有趣,请在他们的官方文档中阅读更多相关信息:https://projectlombok.org/features/experimental/Delegate
第二种方法是将直接委托移动到界面本身:
public interface DataService extends FooDataService, BarDataService {
FooDataService fooService();
BarDataService barService(); // new "accessor" methods in the interface
@Override
default Foo getFoo(){ return fooService().getFoo(); }
@Override
default Foo getBar(){ return barService().getBar(); }
// other delegates here
}
有了这个解决方案,如果你改变了什么,你仍然需要在所有地方改变它。但至少
DataServiceImpl
可以专注于它做的事情,除了代表团