- 浏览: 317336 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (262)
- Java (20)
- 设计模式 (16)
- Oracle (13)
- Struts (1)
- 问题解决 (9)
- ibatis (2)
- Maven (5)
- Git (2)
- 实现原理 (6)
- 敏捷开发 (22)
- Spring (4)
- 算法 (8)
- MySQL (2)
- Java工具箱 (17)
- jQuery (1)
- 英语学习 (8)
- 杂谈 (15)
- 多线程 (15)
- Java解惑 (7)
- Linux (1)
- 重构36计 (6)
- 网络 (4)
- PHP (1)
- Socket (6)
- 面试 (1)
- JVM (14)
- 历史与故事 (5)
- 报表 (4)
- CMS (3)
- Windows (1)
- nginx (5)
- 架构设计 (7)
- RubyOnRails (2)
- Hadoop (8)
- Go (7)
- JS (1)
- Web (1)
- 项目实例 (5)
- ubuntu (4)
最新评论
-
jacking124:
按照你这个配置以后提示这个异常?Exception occur ...
Go语言学习:开发环境搭建及Hello World -
焦志广:
有请看http://jiaozhiguang-126-com. ...
Hadoop白皮书(1):分布式文件系统HDFS简介 -
w156445045:
Hadoop 有没windows环境下的配置呢,
谢谢。非常感 ...
Hadoop白皮书(1):分布式文件系统HDFS简介 -
xiangxm:
学习了。
Java 解惑知多少六 -
焦志广:
xhh_lite 写道怎么少了一个类?恩?不少啊,少那个类啊; ...
易学设计模式四 命令模式(Commond)
国庆节刚过,应一些朋友的提问,总结一下Spring中IOC也即DI的通俗理解。
IOC、DI模式
1.依赖
依赖就是有联系,有地方使用到它就是有依赖它,一个系统不可能完全避免依赖。如果你的一个类或者模块在项目中没有用到它,恭喜你,可以从项目中剔除它或者排除它了,因为没有一个地方会依赖它。下面看一个简单的示例:
/// <summary> /// 用户播放媒体文件 /// </summary> public class OperationMain { public void playMedia() { MediaFile _mtype = new MediaFile(); Player _player = new Player(); _player.play(_mtype); } } /// <summary> /// 播放器 /// </summary> public class Player { public void play(MediaFile file){ } } /// <summary> /// 媒体文件 /// </summary> public class MediaFile { }
上面是一个用户用播放器播放文件简单示例,用户操作是OperationMain类中的playMedia方法,打开一个播放器,选择一个文件来播放。先看看他们之间的依赖关系,可以简单找到有3个依赖
Player依赖MediaFile
OperationMain依赖Player
OperationMain依赖MediaFile
2.依赖倒置
需求增加了,要用不同的播放器,播放不同的文件,我们要抽象出来,减少耦合。
耦合关系就是依赖关系,如果依赖关系相当繁杂,牵一发而动全身,很难维护;依赖关系越少,耦合关系就越低,系统就越稳定,所以我们要减少依赖。
幸亏Robert Martin大师提出了面向对象设计原则----依赖倒置原则:
A. 上层模块不应该依赖于下层模块,它们共同依赖于一个抽象。
B. 抽象不能依赖于具象,具象依赖于抽象。
理解:A.上层是使用者,下层是被使用者,这就导致的结果是上层依赖下层了,下层变动了,自然就会影响到上层了,导致系统不稳定,甚至是牵一发而动全身。那怎么减少依赖呢?就是上层和下层都去依赖另一个抽象,这个抽象比较稳定,整个就来说就比较稳定了。
B.面向对象编程时面向抽象或者面向借口编程,抽象一般比较稳定,实现抽象的具体肯定是要依赖抽象的,抽象不应该去依赖别的具体,应该依赖抽象。
上面播放器的示例中,我们已经找到依赖关系了,现在我们要按照依赖倒置原则,来进行优化。
根据原则如下改动:
Player依赖MediaFile,好办,让Player和MediaFile都去依赖一个抽象IMediaFile
OperationMain依赖Player,好办,让OperationMain和Player都依赖一个抽象IPlayer
OperationMain依赖MediaFile,好办,让OperationMain和MediaFile都依赖一个抽象IMediaFile
IPlayer不能依赖具体MediaFile,应该依赖于具体MediaFile的抽象IMediaFile
package ioc; public class OperationMain { public void playMedia(IPlayer iplayer, IMediaFile imediaFile) { iplayer.play(imediaFile); } }
package ioc; public interface IMediaFile { public void getSetPath(); }
package ioc; public class Mp3File implements IMediaFile { @Override public void getSetPath() { // TODO Auto-generated method stub System.out.println("播放 [Mp3] 格式的文件"); } }
package ioc; public class Mp4File implements IMediaFile { @Override public void getSetPath() { // TODO Auto-generated method stub System.out.println("播放 [Mp4] 格式的文件"); } }
package ioc; public interface IPlayer { public void play(IMediaFile imediaFile); }
package ioc; public class Player implements IPlayer { @Override public void play(IMediaFile imediaFile) { imediaFile.getSetPath(); } }
package ioc; import org.junit.Test; public class IocTest { @Test public void testIoc() { OperationMain opmn = new OperationMain(); opmn.playMedia(new Player(), new Mp3File()); opmn.playMedia(new Player(), new Mp4File()); } }
运行结果:
播放 [Mp3] 格式的文件
播放 [Mp4] 格式的文件
上面代码进行了抽象,可以看到,目的是减少了依赖,但是看上去依赖关系增加了,如用户PlayMedia方法,依赖还增加了依赖接口和具体的实现,但是接口是稳定的,可以不考虑,具体的实现才是变动的,这个依赖还是要的,要播放文件,必定要用到具体的播放器和具体文件。
3.控制反转(IoC)/依赖注入(DI)
强调一下,IOC跟DI要表达的是一个意思
现实生活中,是具体的播放器和具体的媒体文件没有关系,你给它一个Mp3文件他可以播放,给它一个Mp4文件它也可以播放,你删掉你的媒体文件,播放器照样在,具体什么播放器,播放什么文件,控制权全部是我们用户自己。
上面的示例中基本实现了隔离,具体的播放器跟具体的媒体隔离了,具体的播放器只跟媒体接口和播放器接口有关。但是PlayMedia的方法里面的具体对象,写死了,控制权非常小,如果我想用百度影音播放呢,我想换一首音乐呢,只能重新改代码,那控制怎么进行转移呢?
我们可以通过反射来创建,把具体的文件名写在配置文件里,这时候客户端代码也不用变了,只需要改配置文件就好了,稳定性又有了提高
这个具对象是哪一个,全由配置文件来控制了,这个具体对象的控制权交给了配置文件了,这也是人们常说的控制反转。
控制反转IoC是Inversion of Control的缩写,是说对象的控制权进行转移,转移到第三方,比如转移交给了IoC容器,它就是一个创建工厂,你要什么对象,它就给你什么对象,有了IoC容器,依赖关系就变了,原先的依赖关系就没了,它们都依赖IoC容器了,通过IoC容器来建立它们之间的关系。
ref:http://blog.csdn.net/m13666368773/article/details/8053138
发表评论
-
Easy Explorer 插件安装 下载
2015-02-06 10:37 1593Easy Explorer是一个Eclipse插件,主要用于快 ... -
位运算
2012-11-15 10:48 755一、位运算符C语言提供了六种位运算符: & 按位与 ... -
Java API Design Guidelines
2012-11-14 20:00 1010ref:http://www.artima.com/weblo ... -
代码的味道
2012-11-17 18:50 733什么时候需要Refactoring? ... -
如何提高代码质量三 可变更性
2012-11-11 14:21 1055c. 适配器模式 我 ... -
如何提高代码质量二 可维护性
2012-11-11 14:21 15622. 可维护性 软件的 ... -
如何提高代码质量一 可读性
2012-11-11 14:21 1026高质量代码的三要素 ... -
生成Myeclipse的注册码
2012-10-17 11:30 0public class MyEclipseGen { ... -
位运算符在Java编码中的两个应用
2012-10-03 22:27 1028位运算符用于处理整型 ... -
java关键字——strictfp
2012-10-01 10:30 866strictfp, 即 strict float point ... -
Java 异常处理
2012-09-21 16:06 1204为什么要在J2EE项目中谈异常处理呢?可能许多java初学者 ... -
String,StringBuffer与StringBuilder的区别
2012-09-18 18:03 572String 字符串常量 StringBuffer字符串变量( ... -
Java NIO缓冲区内部实现机制
2012-09-17 14:03 837缓冲区内部实现 ... -
Java NIO核心概念及基本读写
2012-09-15 23:30 16271. 引言 I/O流或者输入/输出流指的是计算机 ... -
Java中十个常见的违规编码
2012-09-12 12:43 698最近,我给Java项目做了 ... -
Java 基本数据类型及运算
2012-09-10 22:09 709基本数据类型 int n = 7, m = ... -
Java 进制转换
2012-09-10 16:03 85410进制转16进制 10转2进制 package com ... -
System.arraycopy方法的使用
2012-09-09 22:08 931package com.jiaozg.test; i ... -
Java 泛型学习
2012-09-05 13:50 791Java泛型由来的动机 理解Java泛型最简单的方法是把它看成 ... -
Java 反射例子
2012-08-28 18:04 752Java语言允许通过程序化的方式间接对Class进行操作,Cl ...
相关推荐
什么是spring,spring核心,spring优点,spring体系结构, 入门案例,DI基础,核心API,文档内附代码
spring ioc di aop详解
详细讲解了springioc的各种注入方式以及对应的java方式。讲解了springioc和DI的区别,以及注入特殊复杂的属性
Spring IOC AOP MVC 简单例子
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找...
SpringIOC,DI+dynamic proxy 实现盗版AOP的源代码
day-Spring IoC & DI.md
笔记28-JAVAEE之Spring IoC&DI
spring-core:核心模块 依赖注入IOC和DI的最基本实现 spring-beans:Bean工厂与装配 spring-context:上下文,即IOC容器 spring-context-support:对IOC的扩展,以及IOC子容器 spring-context-indexer:类管理组件和...
SpringIoC和DI注解开发.pdf
简洁版的spring ioc自行实现,不到10个类,描述了加载机制,是研究IOC DI的好材料,能够了解IOC原理。目标是了解基本原理,所以没考虑循环引用的情况 完整的ECLIPSE工程,直接导入就可使用。 里面有测试例子,单步...
day2-Spring IOC 和 DI 注解开发.md
主要介绍了SpringIOC——DI循环依赖,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
Java Spring相关设计思想解析IOC DI DL DP
什么是Ioc和DI
二,Spring IOC以及整合对应源代码 Spring IOC,DI,spring整合mybatis,spring整合servlet
帮助初学者理解spring框架,有助于提高代码能力java.sql.SQLException: Duplicate entry '2' for key 'PRIMARY' Query: insert into transaction values(?,?,?,?,?) Parameters: [2, 6212999999999, 转出, 6000000, ...
引入了第三方——Spring这个BeanFactory,由它来解决Bean之间的依赖问题,达到了松耦合的效果;这个只是原因之一,还有一个更加重要的原因:在没有
Spring Ioc DI 时序图分享给大家,希望对大家看源码有所帮助,不足之处欢迎批评指正,可以在下方留言
文章Spring项目IOC入门案例、文章Spring项目DI入门案例的原代码。方便大家沟通学习。