类是否应该与配置类具有“has-a”关系?

时间:2017-07-24 19:35:57

标签: dependency-injection

我已经看到了一些关于在类中包装一组配置属性的问题,但没有看到如何实际使用它。给定一个配置类(为了简洁省略getter和setter):

class ServiceConfiguration {
    private String foo;     
}

服务类是否应该直接使用配置?

static class SomeServiceB {
    private ServiceConfiguration configuration;

    public SomeServiceB(ServiceConfiguration configuration) {
        this.configuration = configuration;
    }

    public void printIt() {
        System.out.println(configuration.getFoo());
    }
} 

或者它应该只关注foo的实际价值?例如:

static class SomeServiceA {
    private String foo;

    public SomeServiceA(String foo) {
        this.foo = foo;
    }

    public void printIt() {
        System.out.println(foo);
    }
}

我认为SomeServiceA是优越的,因为较低的耦合和关注点分离。

1 个答案:

答案 0 :(得分:0)

两种解决方案都是正确的。重要的是,类只依赖于它实际使用的配置值。

这意味着注入一个包含所有配置值的ApplicationConfiguration对象,或允许访问所有应用程序配置值是一个坏主意,因为这使得不清楚该类实际使用的配置值并推迟读取配置值可能导致配置错误只能很晚才弹出。口头禅是:快速失败。

注入一个封装类所需值的对象通常比在单独的构造函数参数中注入所有这些值更方便。这基本上是Parameter Object refactoring

将配置值(即使它只是一个)包装到参数对象中的另一个好处是,它允许DI容器自动连接此类。当类具有除配置值之外的依赖项时,这尤其有用。例如:

class SomeServiceB {
    public SomeServiceB(IDep1 d1, IDep2 d2, SomeServiceConfig config) {
    }
} 

DI容器不能轻易地自动连接原始值,因为字符串和整数之类的值是不明确的:您可能有多个具有不同含义的值的实例。例如,您可能同时拥有连接字符串和文件路径。两者都是字符串。

重要的是,使配置对象不可变,以便清楚地通信它们无法更改。您通常应该在应用程序启动时构造它们并将它们注册为单例。