切换导航
首页
技术问答
编程语言
前端开发
移动开发
开发工具
程序设计
行业应用
CMS系统
服务器
频道导航
▸ PHP
▸ Java
▸ Java SE
▸ Python
▸ C#
▸ C&C++
▸ Ruby
▸ VB
▸ asp.Net
▸ Go
▸ Perl
▸ netty
▸ Django
▸ Delphi
▸ Jsp
▸ .NET Core
▸ Spring
▸ Flask
▸ Springboot
▸ SpringMVC
▸ Lua
▸ Laravel
▸ Mybatis
▸ Asp
▸ Groovy
▸ ThinkPHP
▸ Yii
▸ swoole
▸ HTML
▸ HTML5
▸ JavaScript
▸ CSS
▸ jQuery
▸ Bootstrap
▸ Angularjs
▸ TypeScript
▸ Vue
▸ Dojo
▸ Json
▸ Electron
▸ Node.js
▸ extjs
▸ Express
▸ XML
▸ ES6
▸ Ajax
▸ Flash
▸ Unity
▸ React
▸ Flex
▸ Ant Design
▸ Web前端
▸ 微信小程序
▸ 微信公众号
▸ iOS
▸ Android
▸ Swift
▸ Hybrid
▸ Cocos2d-x
▸ Flutter
▸ Xcode
▸ Silverlight
▸ cocoa
▸ Cordova
前端之家
设计模式
Ioc(控制反转) DI(依赖注入)
Ioc(控制反转) DI(依赖注入)
2020-06-16
设计模式
前端之家
前端之家
收集整理的这篇文章主要介绍了
Ioc(控制反转) DI(依赖注入)
,
前端之家
小编觉得挺不错的,现在分享给大家,也给大家做个参考。
IoC
IoC
:
Inversion of Control
,控制反转,
控制权从应用程序转移到框架(如
IoC
容器),是
框架共有特性
1、
为什么需要
IoC
容器
1.1
、
应用程序主动控制
对象的实例化及依赖装配
@H_
502
_76@
Java
代码
Aa=
new
AImpl();
Bb=
new
BImpl();
a.setB(b);
本质:创建对象,主动实例化,直接
获取
依赖,主动装配
缺点:更换实现需要重新编译源
代码
很难更换实现、难于测试
耦合实例生产者和实例消费者
@H_
502
_76@
Java
代码
Aa=AFactory.createA();
Bb=BFactory.createB();
a.setB(b);
本质:创建对象,被动实例化,间接
获取
依赖,主动装配
(简单工厂)
缺点:更换实现需要重新编译源
代码
很难更换实现、难于测试
@H_
502
_76@
Java
代码
Aa=Factory.create(“a”);
Bb=Factory.create(“b”);
a.setB(b);
<!—配置.properties-->
@H_
502
_76@
Xml
代码
a
=
AImpl
b
=
BImpl
本质:创建对象,被动实例化,间接
获取
依赖,
主动装配
(工厂
+
反射
+properties
配置文件
、
Service Locator
、
注册
表)
缺点:冗余的依赖装配逻辑
我想直接:
//返回装配好的a
@H_
502
_76@
Java
代码
Aa=Factory.create(“a”);
1.2、可配置通用工厂:
工厂主动控制
,应用程序被动接受,控制权从应用程序转移到工
厂
@H_
502
_76@
Java
代码
//返回装配好的a
Aa=Factory.create(“a”);
<!—
配置文件
-->
@H_
502
_76@
Java
代码
<beanid=“a”
class
=“AImpl”>
<propertyname=“b”ref=“b”/>
</bean>
<beanid=“b”
class
=“BImpl”/>
本质:创建对象和装配对象,
被动实例化,被动接受依赖,被动装配
(工厂
+
反射
+xml
配置文件
)
缺点:不通用
步骤:
1
、读取
配置文件
根据
配置文件
通过反射
创建
AImpl
2
、发现
A
需要一个类型为
B
的
属性
b
3
、到工厂中找名为
b
的对象,发现没有,读取
配置文件
通过反射创建
BImpl
4
、将
b
对象装配到
a
对象的
b
属性
上
【
组件的配置与使用分离开(解耦、更改实现无需
修改
源
代码
、易于更好实现) 】
1.3
、
IoC(
控制反转
)
容器:
容器主动控制
@H_
502
_76@
Java
代码
//返回装配好的a
Aa=ApplicationContext.getBean(“a”);
<!—
配置文件
-->
@H_
502
_76@
Java
代码
<beanid=“a”
class
=“AImpl”>
<propertyname=“b”ref=“b”/>
</bean>
<beanid=“b”
class
=“BImpl”/>
本质:创建对象和装配对象、管理对象生命周期
被动实例化,被动接受依赖,被动装配
(工厂
+
反射
+xml
配置文件
)
通用
IoC
容器:实现了
IoC
思想的容器就是
IoC
容器
2、IoC
容器特点
【
1
】
无需主动
new
对象;而是描述对象应该如何被创建即可
IoC
容器帮你创建,即被动实例化;
【
2
】不需要主动装配对象之间的依赖关系,而是描述需要哪个服务(组件),
IoC
容器会帮你装配(即负责将它们关联在一起),被动接受装配;
【
3
】主动变被动,好莱坞法则:别打电话给我们,我们会打给你;
【
4
】迪米特法则(最少知识原则):不知道依赖的具体实现,只知道需要提供
某类服务的对象(面向抽象编程),松散耦合,一个对象应当对其他对象有尽
可能少的了解
,
不和陌生人(实现)说话
【
5
】
IoC
是一种让服务消费者不直接依赖于服务提供者的组件设计方式,
是一种减少类与类之间依赖的设计原则
。
3、理解
IoC
容器问题关键:
控制的哪些方面被反转了?
1
、谁控制谁?为什么叫反转? ------
IoC
容器控制,而以前是应用程序控制,所以叫反转
2
、控制什么? ------
控制应用程序所需要的资源(对象、
文件
……
)
3
、为什么控制? ------
解耦组件之间的关系
4
、控制的哪些方面被反转了? ------
程序的控制权发生了反转:从应用程序转移到了IoC
容器。
思考:
1: IoC/DI等同于工厂吗?
2: IoC/DI跟以前的方式有什么不一样?
领会:
主从换位的思想
4、实现了
IoC
思想的
容器
就是轻量级容器吗
?
如果仅仅因为使用了控制反转就认为这些轻量级容器与众不同,
就好象在说我的轿车与众不同因为它有四个轮子?
容器:提供组件运行环境,管理组件声明周期(不管组件如何创建的以及组件之间关系如何装配的);
IoC容器不仅仅具有容器的
功能
,而且还具有一些其他特性---如依赖装配
控制反转概念太广泛,让人迷惑,后来
Martin
Fowler
提出依赖注入概念
Martin
Fowler
Inversion of Control Containers and the Dependency Injection pattern
http://martinfowler.com/articles/injection.html
DI
2、什么是
DI
DI
:依赖注入(
Dependency Injection
)
:用一个单独的对象(装配器)来
装配对象之间的依赖关系
。
2、理解
DI
问题关键
谁依赖于谁? -------
应用程序依赖于
IoC
容器
为什么需要依赖? -------
应用程序依赖于
IoC
容器装配类之间的关系
依赖什么东西? -------
依赖了
IoC
容器的装配
功能
谁注入于谁? -------
IoC
容器注入应用程序
注入什么东西? -------
注入应用程序需要的资源(类之间的关系)
更能描述容器其特点的名字
——“
依赖注入
”
(
Dependency Injection
)
IoC
容器应该具有依赖注入
功能
,因此也可以叫
DI
容器
3、DI优点
【
1
】帮你看清组件之间的依赖关系,只需要观察依赖注入的机制(
setter/
构造器),就可以掌握整个依赖(类与类之间的关系)。
【
2
】组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某
种依赖关系注入到组件之中。
【
3
】
依赖注入的目标并非为软件系统带来更多的
功能
,而是为了提升组件重用的概率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何
代码
就可指定目标需要的资源,完成自身的业务逻辑,而不用关心具体的资源来自何处、由谁实现。
使用
DI
限制:
组件和装配器(
IoC
容器)之间不会有依赖关系,因此组件无法从装配器那里获得更多服务,只能获得配置信息中所提供的那些。
4、实现方式
1、构造器注入
2、
setter
注入
3、接口注入:在接口中定义需要注入的信息,并通过接口完成注入
@Autowired
public void prepare(MovieCatalog movieCatalog,
CustomerPreferenceDao customerPreferenceDao) {
this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao;
}
使用
IoC/DI
容器开发需要改变的思路
1、应用程序不主动创建对象,但要描述创建它们的方式。
2、在应用程序
代码
中不直接进行服务的装配,但要
配置文件
中描述哪一个组件需要哪一项服务。容器负责将这些装配在一起。
其原理是基于
OO
设计原则的
The Hollywood Principle
:
Don‘t call us,we’ll call you
(别找我,我会来找你的)。也就是说,所有的组件都是被动的(
Passive
),所有的组件初始化和装配都由容器负责。组件处在一个容器当中,由容器负责管理。
IoC
容器
功能
:
实例化、初始化组件、装配组件依赖关系、负责组件生命周期管理。
本质:
IoC
:控制权的转移,由应用程序转移到框架;
IoC/DI容器:
由
应用程序主动实例化对象
变
被动等待对象(被动实例化);
DI: 由专门的装配器装配组件之间的关系;
IoC/DI容器:
由
应用程序主动装配对象的依赖
变
应用程序被动接受依赖
上一篇:《大话设计模式》——原则:依赖倒
下一篇:vue源码浅析(对象和数组依赖处理)
猜你在找的设计模式相关文章
适配器模式-让不兼容的接口得以适配
适配器模式将一个类的接口转换成客户期望的另一个接口,使得原本接口不兼容的类可以相互合...
作者:前端之家 时间:2021-02-24
策略模式-定义一个算法族
策略模式定义了一系列算法族,并封装在类中,它们之间可以互相替换,此模式让算法的变化独...
作者:前端之家 时间:2021-02-24
设计模式之高质量代码
设计模式讲的是如何编写可扩展、可维护、可读的高质量代码,它是针对软件开发中经常遇到的...
作者:前端之家 时间:2021-02-24
模板方法模式-封装一套算法流程
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,使得子类可以在...
作者:前端之家 时间:2021-02-24
迭代器模式-统一集合的遍历方式
迭代器模式提供了一种方法,用于遍历集合对象中的元素,而又不暴露其内部的细节。
作者:前端之家 时间:2021-02-24
单例模式的五种实现方式及优缺点
单例模式(Singleton Design Pattern)保证一个类只能有一个实例,并提供一个全局访问点。
作者:前端之家 时间:2021-02-24
组合模式-统一的处理个别对象与组合对象
组合模式可以将对象组合成树形结构来表示“整体-部分”的层次结构,使得客户可以用一致的方...
作者:前端之家 时间:2021-02-24
装饰者模式-动态的包装原有对象的行为
装饰者模式能够更灵活的,动态的给对象添加其它功能,而不需要修改任何现有的底层代码。
作者:前端之家 时间:2021-02-24
观察者模式-将消息通知给观察者
观察者模式(Observer Design Pattern)定义了对象之间的一对多依赖,当对象状态改变的时候...
作者:前端之家 时间:2021-02-24
代理模式-访问对象的代理而非其本身
代理模式为对象提供一个代理,来控制对该对象的访问。代理模式在不改变原始类代码的情况下...
作者:前端之家 时间:2021-02-24
编程分类
算法
设计模式
多媒体技术
正则表达式
Elasticsearch
Flink
Hadoop
IDE
最新文章
• 适配器模式-让不兼容的接口
• 策略模式-定义一个算法族
• 设计模式之高质量代码
• 模板方法模式-封装一套算法
• 迭代器模式-统一集合的遍历
• 外观模式-简化子系统的复杂
• 单例模式的五种实现方式及
• 组合模式-统一的处理个别对
• 装饰者模式-动态的包装原有
• 观察者模式-将消息通知给观
热门标签
更多 ►
受约束
摘*
day25
Java常用类库
置信
lamda
留存
持续录入
年后
正则表达式30
3.17
regularexpre
匹
多模
适
20130322
基础理论
pathmunge
涵义
reec
tok
需要转义的特
资源分享
validationex
简明魔法
里弄
形如
源码实现
完备
actionscript