从界面创建全局唯一对象

时间:2014-08-28 18:24:42

标签: java architecture interface singleton

这更像是一个架构问题。我希望在我的项目中有一个全局对象,每个类都可以访问它,但需要它,但不是每次都创建它的实例。对象本身是不同服务的组合。我的第一种方法是定义一个实例化对象的接口,然后只需说出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处理接口的方式也很有趣。它真的只是一个单一(吨)对象,还是为每个类创建一个对象?

2 个答案:

答案 0 :(得分:1)

JVM会像你想要的那样处理接口,只会创建一个SystemServices。 但你所描述的方法确实被认为是“丑陋的”。我认为最好的方法是使用像Spring这样的依赖注入框架。它非常适合您需要的东西 - 拥有其他类可以访问的全局对象。它还使测试变得更加容易,并且还使您能够快速更改应使用的全局对象。

答案 1 :(得分:0)

我不会说它丑陋或骇人听闻。它更不寻常和单一。

它实际上似乎是一种非常好的,轻量级的方法,可以将依赖项注入到所有类中。您必须重新编译接口以更改实现,这在理论上是不好的,但在实践中,并且根据您的要求,可能无关紧要。例如,它将使单元测试变得困难,因为必须重写ServiceProvider接口以提供模拟SecurityService。

我注意到你似乎已经依赖于spring,就像在BlackboxApplication.getAppContext()中一样。为什么不在spring上下文中提供所有服务?是因为你想让那些不受春天管理的课程?由于注释基于弹簧环境的加载,我没有看到任何大的开销,并且spring确实为您购买了许多不错的基础设施代码。

我已经错了你已经使用了春天。如果你不是,我认为你的做法没有错。起初它让我感到惊讶!但那很酷。