程序中解耦应用、IOC概念

1.1 程序中耦合、概念理解

  • 在软件工程中,耦合指的就是对象之间的关联性。对象之间耦合性越高,维护成本就越高。因此对象的设计应使类和构件之间的耦合最小。软件设计中通常用耦合度和内聚度作为衡量模块独立程度的标准。划分模块的一个准则是高内聚、低耦合
  • 高内聚、低耦合:简单来说,就是类内部的关系越紧密越好。类与类之间的关系越少越好

1.2 程序中耦合

1.2.1 代码体现

/**
 * 耦合:
 *        指的是程序中的依赖关系。
 *        依赖关系还有很多种分类。
 *        现在看到的是类的依赖。
 * 解决依赖关系:
 *         使用反射注册驱动
 * 使用反射创建对象产生的问题:
 *         驱动类字符串在代码中写死了,如果遇到修改,又要改源码。
 * 解决写死了字符串的问题:
 *         使用配置文件
 * 
 * 在项目开发中,我们应该做到:
 *        编译器不依赖,运行时才依赖
 */
public class JdbcDemo1 {
   大家思考:如何解决下面的连接数据库代码与数据库驱动代码耦合问题?
   public static void main(String[] args) throws Exception{
      //1.注册驱动
      DriverManager.registerDriver(new com.mysql.jdbc.Driver());
      //2.获取连接
      Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatisdb", "root", "root");
      //3.获取操作数据库的预处理对象
      PreparedStatement pstm = conn.prepareStatement("select * from account");
      //4.执行SQL语句
      ResultSet rs = pstm.executeQuery();

      //5.遍历结果集
      while(rs.next()) {
         System.out.println(rs.getString("name"));
      }
      //6.释放资源
      rs.close();
      pstm.close();
      conn.close();
   }
}

 1.2.2 解决思路

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

1.2.3 思考

  1. 在开发中的三层架构分别是dao、service、controller, 如何降低这三层的耦合度?
  2.  实现的目标: 修改dao的实现,不用修改service层,实现service与dao的解耦。

1.3 实现步骤

1.3.1 准备

dao接口

public interface IAccountDao {
    void save();
}

 实现

public class AccountDaoImpl implements IAccountDao {
    @Override
    public void save() {
        System.out.println("保存账户!");
    }
}

public class AccountDaoOracleImpl implements IAccountDao {
    @Override
    public void save() {
        System.out.println("Oracle保存账户!");
    }
}

service接口

public interface IAccountService {
    void save();
}

实现

public class AccountServiceImpl implements IAccountService {

    // 创建dao
    private IAccountDao accountDao = new AccountDaoImpl();
    
    @Override
    public void save() {
        accountDao.save();
    }
}

1.3.2 工厂解耦

定义properties配置文件


# dao
# default database (mysql)
#accountDao =com.ftjf.dao.impl.AccountDaoImpl
# oracle database
accountDao = com.ftjf.dao.impl.AccountDaoOracleImpl

# service
account

定义工厂

/**
 * 创建对象的工厂,主要加载配置文件创建dao、service对象
 */
public class BeanFactory {

    /**
     * 根据指定的key,读取配置文件创建对象
     * @return
     */
    public static <T> T getBean(String key,Class<T> clazz){
        try {
            // 加载Properties配置文件
            // 通过ResourceBundle加载配置文件:
            // 1. 只可以加载properties后缀的配置文件
            // 2. 只能加载类路径下的properties配置文件
            ResourceBundle bundle = ResourceBundle.getBundle("instance");
            // 根据key获取value:com.htjf.dao.impl.AccountDaoImpl
            String value = bundle.getString(key);
            // 创建对象返回
            return (T)Class.forName(value).getConstructor().newInstance();
        } catch (Exception e) {
            // 异常转型,调用者可以处理可以不处理(灵活)
            throw new RuntimeException(e);
        }
    }
}

修改service


public class AccountServiceImpl implements IAccountService {

    // 创建dao
    //private IAccountDao accountDao = new AccountDaoImpl();
    // 新需求:更换了数据库改为oracle
    //private IAccountDao accountDao = new AccountDaoOracleImpl();
    // 分析:现在更改了数据库,dao重新写了实现,对sevice有影响,要修改代码。
    // 期望:改dao,不修改service代码。(service与dao解耦的设计)

    // 通过工厂创建对象
    private IAccountDao accountDao =  BeanFactory.getBean("accountDao",IAccountDao.class);

    @Override
    public void save() {
        accountDao.save();
    }
}

1.4 Inversion Of Control(IOC)控制反转

  •  前面我们使用了工厂模式,实现了表现层-业务层-持久层的解耦。

  • 它的核心思想是:
    1.通过读取配置文件反射创建对象。
    2.把创建出来的对象都存起来,当我们下次需要使用的时候可以直接从存储位置获取。

  • 什么是控制反转?把对象的创建交给外部的容器,就是控制反转。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hyhcloud

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值