程序的耦合和解耦
程序的耦合和解耦
耦合
指的是程序间的依赖关系,包括类之间的依赖和方法间的依赖
解耦
降低程序间的依赖关系,实际开发中应该做到编译器不依赖,运行时才依赖
解耦的思路
-
使用反射来创建对象,而避免使用new关键字
-
通过读取配置文件来获取要创建的对象的全限定类名
举例
下面请看一个简单的例子,模拟账号保存
该项目的文件结构如图
业务层的接口及其实现类:
package com.itheima.service;
/**
* @Author:Zzq
* @Description:账户的业务层的接口
* @Date:2020/6/13
* @Time:15:50
*/
public interface iAccountService {
/**
*@Author:Zzq
*@Description:模拟保存账户
*@Date:2020/6/13
*@Param: * @param null
*/
void saveAccount();
}
package com.itheima.service.impl;
import com.itheima.factory.BeanFactory;
import com.itheima.mapper.iAccountMapper;
import com.itheima.service.iAccountService;
/**
* @Author:Zzq
* @Description:账号的业务实现类
* @Date:2020/6/13
* @Time:15:53
*/
public class AccountServiceImpl implements iAccountService {
private iAccountMapper accountMapper = new AccountMapperImpl();
@Override
public void saveAccount() {
accountMapper.saveAccount();
}
}
持久层的接口及其实现类
package com.itheima.mapper;
/**
* @Author:Zzq
* @Description:账户的持久层接口
* @Date:2020/6/13
* @Time:16:08
*/
public interface iAccountMapper {
void saveAccount();
}
package com.itheima.mapper.impl;
import com.itheima.mapper.iAccountMapper;
/**
* @Author:Zzq
* @Description:账户的持久层实现类
* @Date:2020/6/13
* @Time:16:10
*/
public class AccountMapperImpl implements iAccountMapper {
public void saveAccount(){
System.out.println("保存了");
}
}
最后是main函数,也是其表现层
package com.itheima.ui;
import com.itheima.factory.BeanFactory;
import com.itheima.service.iAccountService;
/**
* @Author:Zzq
* @Description:模拟一个表现层,用于调用业务
* @Date:2020/6/13
* @Time:22:28
*/
public class Client {
public static void main(String[] args) {
AccountServiceImpl as = new AccountServiceImpl();
as.saveAccount();
}
}
从代码中可以看到,各个层次是相互依赖,层层套用,这样就称之为高耦合,各个代码块之间独立性较差,下面就按照解耦的思路来尽可能降低耦合,如下:
1.在项目文件中新建一个factory包,新建一个BeanFactory类来建立一个bean工厂来创建我们的service和mapper对象,并写好Bean.properties配置文件
package com.itheima.factory;
import java.io.InputStream;
import java.util.Properties;
/**
* @Author:Zzq
* @Description:是一个创建bean对象的工厂
*
* Bean:在计算机英语中,有可重用组件的含义。
* JavaBean:用Java编写的可重用组件。
* Java >> 实体类
* 它就是创建我们的service和mapper对象的。
* 1.需要一个配置文件来配置我们的service和mapper
* 配置的内容:唯一标识 = 全限定类名(key = value)
* 2.通过读取配置文件的配置内容,反射创建对象
*
* 配置文件可以是xml也可以是properties
* @Date:2020/6/13
* @Time:22:36
*/
public class BeanFactory {
//定义一个properties对象
private static Properties props;
//使用静态代码块为Properties对象赋值
static {
try {
//实例化对象
props = new Properties();
//获取properties文件的流对象
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
props.load(in);
}catch (Exception e) {
throw new ExceptionInInitializerError("初始化properties失败");
}
}
/**
*@Author:Zzq
*@Description:根据bean的名称获取bean对象
*@Date:2020/6/13
*@Param: * @param null
*/
public static Object getBean(String beanName){
Object bean = null;
try {
String beanPath = props.getProperty(beanName);
bean = Class.forName(beanPath).newInstance();
}catch (Exception e){
e.printStackTrace();
}
return bean;
}
}
accountService = com.itheima.service.impl.AccountServiceImpl
accountMapper = com.itheima.mapper.impl.AccountMapperImpl
2.修改Client.java和AccountServiceImpl.java代码,使用反射来创建对象
package com.itheima.ui;
import com.itheima.factory.BeanFactory;
import com.itheima.service.iAccountService;
/**
* @Author:Zzq
* @Description:模拟一个表现层,用于调用业务
* @Date:2020/6/13
* @Time:22:28
*/
public class Client {
public static void main(String[] args) {
iAccountService as = (iAccountService) BeanFactory.getBean("accountService");
as.saveAccount();
}
}
package com.itheima.service.impl;
import com.itheima.factory.BeanFactory;
import com.itheima.mapper.iAccountMapper;
import com.itheima.service.iAccountService;
/**
* @Author:Zzq
* @Description:账号的业务实现类
* @Date:2020/6/13
* @Time:15:53
*/
public class AccountServiceImpl implements iAccountService {
private iAccountMapper accountMapper = (iAccountMapper) BeanFactory.getBean("accountMapper");
@Override
public void saveAccount() {
accountMapper.saveAccount();
}
}
以上就是解耦的过程,在使用了BeanFactory了之后,就算是删除掉了service或mapper文件,编译器也不会报错,有人看到这里肯定会说:啊,你这不是脱裤子放屁嘛,明明几个类就能解决的问题非要弄个工厂?其实是这个例子太高简单,还不足以看出低耦合的好处,在以后比较大型的开发中,如果有新的需求要加入,我们就可以只添加几个类就能完成,而不用重新考虑整个程序,避免牵一发而动全身。