本文仅供学习交流使用,侵权必删。
不作商业用途,转载请注明出处
IoC
Inversion of Control principle是一种面向对象的编程设计模式,可以用来降低代码的耦合度。IoC也会被戏称为Hollywood Principle: Don't call us, we'll call you。
对于用传统编程方式开发的程序,每个事件的调用、依赖管理以及组件管理都需要业务系统去完成。
而对于IoC原则开发的程序,将会使用一个框架来进行程序开发,如我们比较熟悉的Spring。框架已经了解常见的行为,我们只需要将完成业务组件的开发注册到框架中。框架能够针对用户触发的事件去调用我们注册进去的业务组件,并且能够帮我们管理这些组件。这种开发方式能有效提高我们的开发效率,工程师只需要专注于业务组件的开发。
IoC设计目的
- 将任务的执行和实现解耦
- 让开发人员专注于设计业务模块代码上
- 利用依赖契约将模块从系统中解放出来
- 避免模块变更时产生的副作用
IoC实现技术:
- 服务定位器模式(service locator pattern)
- 依赖注入
- 依赖查找
- 模板设计模式
- 策略模式
Dependency Injection
在Spring官网中解释IoC一般也被称为依赖注入(Dependency Injection),但其实DI只是IoC的其中一种实现方式。而Spring中的控制反转指的是对于组件的控制权由用户转移到框架中。
传统的方式我们是需要主动去创建或者主动查找具体的实现类。而Spring的IoC是让容器去管理这些组件的生命周期以及注入。
image.png
假设我们有一个授信Controller接口对用户提供授信查询功能。根据DI的基本思想,
授信Controller并不直接依赖授信查询的具体实现类,只依赖于授信查询接口。而具体的实现类是由容器创建并注入到我们的Controller中
DI实现的三种方法
- 构造器注入
- setter注入
- 接口注入
在Spring Framework中,实现了通过构造器注入和setter注入。通过构造器和setter实现DI的优势是只要遵循简单的约定即可(定义好构造器或者定义好setter方法),无需在我们的业务组件中入侵其他非业务代码。
构造器注入 VS setter注入
从Martin Flower的观点和Spring官方文档中可以看到,他们更加倾向于开发人员使用构造器注入的方式。首先带参数的构造器能够清楚说明创建一个有效对象时的含义。其次构造器注入能够确保对象是稳定不变对象,如果开放setter方法有可能会降低对象的稳定性。
但构造器注入也并非一直是best choice,这种方式注入同样存在问题。如果构造器参数过多,会让构造函数看起来较为混乱,可读性较差。其次有过多的构造函数或者过多的继承关系。在初始化时就会调用每个超类的构造函数,这可能导致构造函数爆炸。如果存在上述问题的情况下,setter方法有可能是更好的选择。
参考文献
[wiki] https://en.jinzhao.wiki/wiki/Inversion_of_control
[Inversion of Control Containers and the Dependency Injection pattern] https://www.martinfowler.com/articles/injection.html
[spring官方文档] https://docs.spring.io/spring-framework/docs/5.2.12.RELEASE/spring-framework-reference/core.html#spring-core
网友评论