这更像是一个架构问题。我希望在我的项目中有一个全局对象,每个类都可以访问它,但需要它,但不是每次都创建它的实例。对象本身是不同服务的组合。我的第一种方法是定义一个实例化对象的接口,然后只需说出implements
即可将其注入到每个类中。我想知道的是,如果这种方法是干净的,有点hacky或真的很粗糙。
这是我到目前为止的实现:
public final class SystemServices
{
private final SecurityService securityService;
private final PersistencyService persistencyService;
private final RecordService recordService;
private final DispatcherService dispatcherService;
private SystemServices(Builder builder)
{
this.securityService = builder.securityService;
this.persistencyService = builder.persistencyService;
this.recordService = builder.recordService;
this.dispatcherService = builder.dispatcherService;
}
public SecurityService getSecurityService()
{
return securityService;
}
public PersistencyService getPersistencyService()
{
return persistencyService;
}
public RecordService getRecordService()
{
return recordService;
}
public DispatcherService getDispatcherService()
{
return dispatcherService;
}
public static class Builder
{
private SecurityService securityService;
private PersistencyService persistencyService;
private RecordService recordService;
private DispatcherService dispatcherService;
public Builder setSecurityService(SecurityService securityService)
{
this.securityService = securityService;
return this;
}
public Builder setPersistencyService(PersistencyService persistencyService)
{
this.persistencyService = persistencyService;
return this;
}
public Builder setRecordService(RecordService recordService)
{
this.recordService = recordService;
return this;
}
public Builder setDispatcherService(DispatcherService dispatcherService)
{
this.dispatcherService = dispatcherService;
return this;
}
public SystemServices build()
{
return new SystemServices(this);
}
}
}
这是创建SystemServices实例的接口:
public interface ServiceProvider
{
public static SystemServices systemServices = new SystemServices.Builder()
.setSecurityService(new SecurityService())
.setPersistencyService(new PersistencyService(new BlackBoxDb(BlackboxApplication.getAppContext())))
.setRecordService(new RecordService()).setDispatcherService(new DispatcherService()).build();
}
现在我只需使用systemServices.getSecurityService.doSomethingSecurityRelated()
代码有效,对我来说对初学者来说太好了,但我确信这种方法有些丑陋。所以批评任何批评:) JVM处理接口的方式也很有趣。它真的只是一个单一(吨)对象,还是为每个类创建一个对象?
答案 0 :(得分:1)
JVM会像你想要的那样处理接口,只会创建一个SystemServices。 但你所描述的方法确实被认为是“丑陋的”。我认为最好的方法是使用像Spring这样的依赖注入框架。它非常适合您需要的东西 - 拥有其他类可以访问的全局对象。它还使测试变得更加容易,并且还使您能够快速更改应使用的全局对象。
答案 1 :(得分:0)
我不会说它丑陋或骇人听闻。它更不寻常和单一。
它实际上似乎是一种非常好的,轻量级的方法,可以将依赖项注入到所有类中。您必须重新编译接口以更改实现,这在理论上是不好的,但在实践中,并且根据您的要求,可能无关紧要。例如,它将使单元测试变得困难,因为必须重写ServiceProvider接口以提供模拟SecurityService。
我注意到你似乎已经依赖于spring,就像在BlackboxApplication.getAppContext()中一样。为什么不在spring上下文中提供所有服务?是因为你想让那些不受春天管理的课程?由于注释基于弹簧环境的加载,我没有看到任何大的开销,并且spring确实为您购买了许多不错的基础设施代码。
我已经错了你已经使用了春天。如果你不是,我认为你的做法没有错。起初它让我感到惊讶!但那很酷。