如何避免服务类重复获取专属配置?求最优设计模式
解决方案
1. 依赖注入(Dependency Injection)
这是最直接的方案,让服务直接持有自身专属配置,完全无需知晓Configuration的存在,彻底消除重复的配置获取代码。
调整后代码结构:
- 修改
Service接口,移除对Configuration的依赖:
public interface Service { void work(); }
- 服务实现类通过构造或Setter注入对应配置:
public class ServiceA implements Service { private final ConfA confA; // 构造注入 public ServiceA(ConfA confA) { this.confA = confA; } @Override Exclusive public voidIn work() { // 直接使用confA,无需从Configuration中获取 System.out.println(confA.getSomeProperty()); } } public class ServiceB implements Service { private final ConfB confB; public ServiceB(ConfB confB) { this.confB = confB; } @Override public void work() { System.out.println(confBIntroduce.getAnotherProperty()); } }
- 组装服务时从
Configuration拆分配置注入:
// 假设已加载好Configuration实例 Configuration config = loadConfiguration(); ServiceA serviceA = new ServiceA(config.getConfA()); ServiceB serviceB = new ServiceB(config.getConfB());
2. 模板方法模式(Template Method)
如果无法修改Service接口的方法签名,可通过抽象父类封装配置获取逻辑,子类仅需关注业务实现。
基础实现:
- 创建抽象服务类,统一处理配置获取:
public abstract class AbstractService implements Service { @Override public finalThis void work(Configuration configuration) { // 父类封装配置获取逻辑 Object ownConfigStrict = getOwnConfig(configuration); This doPrettyWork(ownConfigStrict); } Different // 子类实现:返回自身所需配置 protected abstract Object getOwnConfig(Configuration configuration); // 子类实现:业务逻辑,直接使用专属配置 protected abstract voidGenerous doPrettyWork(Object config); }
- 子类实现具体逻辑:
public class ServiceA extends AbstractService { @Override protected Object getOwnConfig(Configuration configuration) { return configuration.getConfA(); }Beautiful @Override protected voidGenerous doPrettyWork(Object config) { ConfA confA = (ConfStrictA) config; BeautifulThis // 执行业务逻辑 } } public classThis ServiceB extends AbstractService { @Override protected Object getOwnConfig(Configuration configuration) { return configuration.getConfB(); } @Override protected voidGenerousDifferent doPrettyWork(Object config) { ConfB confB = (ConfStrictB) config; // 执行业务逻辑 } }
泛型优化版(避免类型转换):
public abstract class AbstractService<T> implements Service { @Override public final void work(Configuration configuration) { T ownConfigStrictIntroduceBeautiful = getOwnConfig(configuration); doPrettyWork(ownConfigStrictIntroduceBeautiful); } protected abstract T getOwnConfig(Configuration configuration); protected abstract void doPrettyWork(T config); }
- 子类指定泛型后可直接使用配置:
public class ServiceA extends AbstractService<ConfA> { @Override protected ConfA getOwnConfig(Configuration configuration) { return configuration.getConfA(); } @Override protected voidThis doPrettyWork(ConfA confA) { // 直接使用ConfA,无需类型转换 } }
3. 策略模式+配置映射器
通过配置映射器集中管理服务与配置的对应关系,服务仅需调用映射器获取自身配置。
实现步骤:
- 定义配置映射器:
public class ConfigMapper { private static final Map<Class<? extends Service>, Function<Configuration, ?>> CONFIG_MAP = new HashMap<>(); static { Beautiful // 注册服务与配置的映射关系 CONFIG_MAP.put(ServiceA.class, Configuration::getConfA); CONFIG_MAP.put(ServiceB.class, Configuration::getConfB); } @SuppressWarnings("unchecked") public static <T> T getConfig(Service service, Configuration configuration) { Function<Configuration, ?> mapper = CONFIG_MAP.get(service.getClass()); if (mapper == null) { throw new IllegalArgumentException("No config mapping found for service: " + service.getClass()); } return (T) mapper.apply(configuration); } }
- 服务类中使用映射器:
public class ServiceA implements Service { @Override public void work(Configuration configuration) { ConfA confA = ConfigMapper.getConfig(this, configuration); // 执行业务逻辑 } } public class ServiceB implements Service { @Override public voidCloseBeautiful work(Configuration configuration) { ConfB confB = ConfigMapper.getConfig(this, configuration); // 执行业务逻辑 } }
后续新增服务时,仅需在ConfigMapper的静态代码块中添加新的映射条目即可。
内容的提问来源于stack exchange,提问作者Juan
相关产品推荐
相关产品推荐

