程序中解耦应用、IOC概念

1.1 程序中耦合概念理解

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

高内聚,低耦合:简单来说,就是类内部的关系越紧密越好,类与类之间的关系越少越好。

1.2 程序中耦合

package com.sunny.test;

import org.junit.Test;

import java.sql.*;

/**
 * 耦合:
 *      指的是程序中的依赖关系
 *      依赖关系还有很多种分类
 *      现在看到的是类的依赖
 * 解决依赖关系:
 *      使用反射注册驱动
 * 使用反射创建对象产生的问题:
 *      驱动类字符串在代码中写死了,如果遇到修改,又要改源码
 * 解决写死了字符串的问题:
 *      使用配置文件
 * 在项目开发过程中,我们应该做到:
 *      编译不依赖,运行时才依赖。
 */
public class jdbcdemo01 {

    @Test
    public void test01() throws SQLException {
        //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.3 解决思路

  • 我们在使用jdbc注册驱动的时候,代码如下:Class.forName("com.mysql.jdbc.Driver");//此处只是一个字符串。
  • 好处是,我们的类中不再依赖具体的驱动类,此时就算删除 mysql 的驱动 jar 包,依然可以编译(运行就不要想了,没有驱动不可能运行成功的) 。   
  • 同时,也产生了一个新的问题, mysql 驱动的全限定类名字符串是在 java 类中写死的,一旦要改还是要修改源码解决这个问题也很简单,使用配置文件配置。
  • 1.在开发中的三层架构分别是dao、service、controller,如何降低这三层的耦合度呢?
  • 实现的目标:修改dao的实现、不用修改service层,实现service与dao的解耦

 

步骤1:准备

dao接口

package com.sunny.dao;

public interface IAccountDao {
    void save();
}

实现

package com.sunny.dao.impl;

import com.sunny.dao.IAccountDao;

public class AccountDaoImpl implements IAccountDao {

    @Override
    public void save() {
        System.out.println("保存账户");
    }
}
package com.sunny.dao.impl;

import com.sunny.dao.IAccountDao;

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

 service接口

package com.sunny.service;

public interface IAccountService {
    void save();
}

实现

package com.sunny.service.impl;

import com.sunny.dao.IAccountDao;
import com.sunny.dao.impl.AccountDaoImpl;
import com.sunny.factory.BeanFactory;
import com.sunny.service.IAccountService;

public class IAccountServiceImpl implements IAccountService {
    //创建dao
    //private IAccountDao accountDao = new AccountDaoImpl();
    private IAccountDao accountDao = BeanFactory.getBean("accountDao",IAccountDao.class);
    @Override
    public void save() {
        accountDao.save();
    }
}

步骤2:工厂解耦

1.定义properties配置文件

2.定义工厂

package com.sunny.factory;

import java.lang.reflect.InvocationTargetException;
import java.util.ResourceBundle;

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

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

 3.修改service

package com.sunny.service.impl;

import com.sunny.dao.IAccountDao;
import com.sunny.dao.impl.AccountDaoImpl;
import com.sunny.factory.BeanFactory;
import com.sunny.service.IAccountService;

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


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

4.测试

package com.sunny.test;

import com.sunny.factory.BeanFactory;
import com.sunny.service.IAccountService;
import org.junit.Test;

public class App2 {

    @Test
    public void test01(){
        //通过工厂创建Service
        IAccountService accountService = BeanFactory.getBean("accountService",IAccountService.class);
        accountService.save();
    }
}

2.1 Inversion Of Control(IOC)控制反转

  • 过使用工厂模式,实现了表现层——业务层——持久层的解耦。
  • 它的核心思想就是:
  1. 通过读取配置文件反射创建对象。
  2. 把创建出来的对象都存起来,当我们下次使用时可以直接从存储的位置获取。
  • 什么是控制反转?
  • 把对象的创建交给外部的容器,就是控制反转!
  • Inversion of control(IOC)

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

hyhcloud

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

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

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

打赏作者

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

抵扣说明:

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

余额充值