工厂类使用依赖注入是否为不良实践?框架DI与方案A/B如何抉择?
你的工厂类DI与方案选择问题解答
嘿,咱们来逐个解决你的疑问:
1. 工厂类中使用依赖注入是不是不良实践?
完全不是!这其实是非常推荐的实践方式。
工厂类本身也可能需要依赖外部资源(比如你的PropertyManager),通过依赖注入的方式引入这些依赖,有几个明显的好处:
- 降低耦合:工厂不需要硬编码创建依赖实例,而是由容器注入,后续替换依赖实现(比如测试用的Mock)会非常方便。
- 依赖清晰:通过
@Autowired标注,能明确看到工厂依赖哪些组件,可读性更强。 - 符合IoC原则:把依赖的创建权交给容器,符合控制反转的设计思想,让代码更易于维护和扩展。
2. 是否应当让框架的使用者负责处理依赖注入?
绝对不应该。
作为框架开发者,你的核心目标是让使用者尽可能少地关注底层细节,专注于业务逻辑。如果让使用者手动传递PropertyManager这类框架内部依赖:
- 增加了使用者的心智负担,他们需要了解框架内部的依赖结构,这违背了框架封装的初衷。
- 容易出错:使用者可能传递错误的实例,或者不知道该从哪里获取正确的依赖实例。
- 降低了框架的易用性:理想状态下,使用者只需要传入业务相关的参数(比如你的示例中的
"hello"),其余的依赖管理都由框架自动处理。
3. 方案A vs 方案B:选哪个?
毫无疑问选方案A,理由如下:
方案A的优势:
- 解耦性更强:使用者(
SomeUserClass)不需要知道SMSAction依赖PropertyManager,只需要调用actionFactoryService.createAction("hello")即可,符合迪米特法则(最少知识原则)。 - 可维护性更高:如果以后
SMSAction的依赖发生变化(比如新增一个Logger),只需要修改SMSActionFactoryService的createAction方法,使用者的代码完全不需要改动。 - 测试更友好:在测试
SomeUserClass时,你可以轻松MockSMSActionFactoryService,返回模拟的SMSAction实例,不需要关心PropertyManager的细节。 - 贴合Spring生态:方案A利用Spring的DI机制,和框架的整合更自然,也能享受到Spring提供的事务、AOP等特性。
方案B的缺点:
- 强迫使用者了解
SMSAction的内部依赖,增加了使用成本。 - 代码耦合度高:如果
SMSAction的构造参数变化,所有调用SMSActionFactory.createAction的地方都需要修改。 - 不符合IoC思想,把依赖管理的责任推给了使用者,违背了框架的设计初衷。
小提示:你的代码里有两处小错误
注意看你的代码实现:
SMSActionFactoryService的createAction方法返回类型写错了,应该返回SMSAction而非SMSActionFactoryService:
// 修正后 public SMSAction createAction(String message) { return new SMSAction(properties, message); }
SMSActionFactory的createAction方法返回类型也应该是SMSAction,而非SMSActionFactory:
// 修正后 public static SMSAction createAction(PropertyManager properties, String message) { return new SMSAction(properties, message); }
内容的提问来源于stack exchange,提问作者Paul White
相关产品推荐
相关产品推荐

