本文介绍一种通过依赖注入简化服务类获取专属配置的模式,避免在每个服务中重复调用 `configuration.getxxx()`,提升代码内聚性与可测试性。
在典型的分层配置架构中,Configuration 作为顶层聚合对象,封装多个子配置(如 ConfA、ConfB),而各服务(ServiceA、ServiceB)仅需其中一部分。若强制所有服务接收完整 Configuration 对象,不仅违背单一职责原则,还会导致冗余访问逻辑和隐式耦合。
推荐方案:面向配置契约的接口级依赖注入
核心思想是——让每个服务直接声明其真正需要的配置类型,而非整个 Configuration。这可通过重构 Service 接口实现:
// 原始泛化接口(不推荐)
public interface Service {
void work(Configuration configuration);
}应升级为泛型化或专用化接口,例如:
// 方案一:泛型接口(更灵活,支持统一调度) public interface Service{ void work(T config); } public class ServiceA implements Service { @Override public void work(ConfA confA) { // 直接使用 confA,零胶水代码 System.out.println("Using A config: " + confA.getHost()); } } public class ServiceB implements Service { @Override public void work(ConfB confB) { System.out.println("Using B config: " + confB.getTimeout()); } }
或采用更清晰的专用接口(语义更强,利于 IDE 提示与编译检查):
public interface ServiceA {
void execute(ConfA config);
}
public interface ServiceB {
void execute(ConfB config);
}配套的启动/协调层负责装配:
public class ConfigurationLoader {
private final Configuration configuration;
public ConfigurationLoader(Configuration configuration) {
this.configuration = configuration;
}
public void
runAllServices() {
new ServiceA().execute(configuration.getConfA());
new ServiceB().execute(configuration.getConfB());
// 或通过 Spring 等容器自动注入:@Autowired private ServiceA serviceA;
}
}✅ 优势总结:
⚠️ 注意事项:
该模式本质是将“配置解析责任”上移至装配层,使业务服务回归纯粹逻辑表达,是构建高内聚、低耦合配置驱动系统的关键实践。