IoC的概念和作用

IoC的概念和作用

1.什么是程序的耦合
在这里插入图片描述
内聚和耦合是密切相关的,同其他模块存在高耦合的模块意味着低内聚,而高内聚的模块意味着该模块同其他模块之间是低耦合。在进行软件设计时,应力争做到高内聚,低耦合。

2.耦合的体现

早期我们的 JDBC 操作,注册驱动时,我们为什么不使用 DriverManager 的 register 方法,而是采
用 Class.forName 的方式?
原因就是:我们的类依赖了数据库的具体驱动类(MySQL),如果这时候更换了数据库品牌(比如 Oracle),
需要修改源码来重新数据库驱动。这显然不是我们想要的。
/**
* 程序的耦合
* 耦合:程序间的依赖关系
* 包括:
* 类之间的依赖
* 方法间的依赖
* 解耦:
* 降低程序间的依赖关系
* 实际开发中:
* 应该做到:编译期不依赖,运行时才依赖。
* 解耦的思路:
* 第一步:使用反射来创建对象,而避免使用 new 关键字。
* 第二步:通过读取配置文件来获取要创建的对象全限定类名
*/
public class JdbcDemo1 {
public static void main(String[] args) throws Exception{
//1.注册驱动
// DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
//3.获取操作数据库的预处理对象
//4.执行 SQL,得到结果集
//5.遍历结果集
//6.释放资源
}
}

3.解决耦合的思路
当是我们讲解 jdbc 时,是通过反射来注册驱动的,代码如下:
Class.forName(“com.mysql.jdbc.Driver”);//此处只是一个字符串
此时的好处是,我们的类中不再依赖具体的驱动类,此时就算删除 mysql 的驱动 jar 包,依然可以编译(运行就不要想了,没有驱动不可能运行成功的)。同时,也产生了一个新的问题,mysql 驱动的全限定类名字符串是在 java 类中写死的,一旦要改还是要修改源码。解决这个问题也很简单,使用配置文件配置。

4.工厂模式解耦
在实际开发中我们可以把三层的对象都使用配置文件配置起来,当启动服务器应用加载的时候,让一个类中的方法通过读取配置文件,把这些对象创建出来 并存起来。在接下来的使用的时候,直接拿过来用就好了。那么,这个读取配置文件,创建和获取三层对象的类就是工厂。

久层:
/**
* 账户的持久层接口
* @author 黑马程序员
* @Company http://www.ithiema.com
*/
public interface IAccountDao {
/**
* 模拟保存账户
*/
void saveAccount();
}
/**
* 账户的持久层实现类
* @author 黑马程序员
* @Company http://www.ithiema.com
* @create 2018-01-01
*/
public class AccountDaoImpl implements IAccountDao {
public void saveAccount(){
System.out.println(" 保存了账户");
}
}
业务层:
/**
* 账户业务层的接口
* @author 黑马程序员
* @Company http://www.ithiema.com
*/
public interface IAccountService {
/**
* 模拟保存账户
*/
void saveAccount();
}
/**
* 账户的业务层实现类
* @author 黑马程序员
* @Company http://www.ithiema.com
*/
public class AccountServiceImpl implements IAccountService {
//private IAccountDao accountDao = new AccountDaoImpl();
private IAccountDao accountDao =
(IAccountDao)BeanFactory.getBean("accountDao");
public void saveAccount(){
accountDao.saveAccount();
}
}
表现层:
/**
* 模拟一个表现层,用于调用业务层
* @author 黑马程序员
* @Company http://www.ithiema.com
*/
public class Client {
public static void main(String[] args) {
//IAccountService as = new AccountServiceImpl();
IAccountService as = (IAccountService) BeanFactory.getBean("accountService");
as.saveAccount();
}
}
通过上面的代码我们可以看出:
过 绿色被注释上的部分就是我们程序中的耦合体现。而下面的通过 BeanFactory 中 中 getBean  方法获取对
象就解决了我们代码中对具体实现类的依赖。
工厂类:
/**
* 一个创建 Bean 对象的工厂
*
* 第一个:需要一个配置文件来配置我们的 service 和 dao
* 配置的内容:唯一标识=全限定类名(key=value)
* 第二个:通过读取配置文件中配置的内容,反射创建对象
* 我的配置文件可以是 xml 也可以是 properties
*/
public class BeanFactory {
//定义一个 Properties 对象
private static Properties props;
//定义一个 Map,用于存放我们要创建的对象。我们把它称之为容器
private static Map<String,Object> beans;
//使用静态代码块为 Properties 对象赋值
static {
try {
//实例化对象
props = new Properties();
//获取 properties 文件的流对象
InputStream in =
BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
props.load(in);
//实例化容器
beans = new HashMap<String,Object>();
//取出配置文件中所有的 Key
Enumeration keys = props.keys();
//遍历枚举
while (keys.hasMoreElements()){
//取出每个 Key
String key = keys.nextElement().toString();
//根据 key 获取 value
String beanPath = props.getProperty(key);
//反射创建对象
Object value = Class.forName(beanPath).newInstance();
//把 key 和 value 存入容器中
beans.put(key,value);
}
}catch(Exception e){
throw new ExceptionInInitializerError(" 初始化 properties  失败!");
}
}
/**
* 根据 bean 的名称获取对象
* @param beanName
* @return
*/
public static Object getBean(String beanName){
return beans.get(beanName);
}
}
配置文件:
accountService=com.itheima.service.impl.AccountServiceImpl
accountDao=com.itheima.dao.impl.AccountDaoImpl

5.控制反转

上一小节我们通过使用工厂模式,实现了表现层——业务层以及业务层——持久层的解耦。
它的核心思想就是:
1、通过读取配置文件反射创建对象。
2、把创建出来的对象都存起来,当我们下次使用时可以直接从存储的位置获取。
这里面要解释两个问题:
第一个:存哪去?
分析:由于我们是很多对象,肯定要找个集合来存。这时候有 Map 和 List 供选择。
到底选 Map 还是 List 就看我们有没有查找需求。有查找需求,选 Map。
所以我们的答案就是
在应用加载时,创建一个 Map,用于存放三层对象。
我们把这个 map 称之为 容器。
第二个: 什么是工厂?
工厂就是负责给我们从容器中获取指定对象的类。这时候我们获取对象的方式发生了改变。
原来:
我们在获取对象时,都是采用 new 的方式。是主动的。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值