spring-程序的耦合
什么是程序的耦合?
耦合性(Coupling),也叫耦合度,是对模块间关联程度的度量。耦合的强弱取决于模块间接口的复杂性、调
用模块的方式以及通过界面传送数据的多少。模块间的耦合度是指模块之间的依赖关系,包括控制关系、调用关
系、数据传递关系。模块间联系越多,其耦合性越强,同时表明其独立性越差( 降低耦合性,可以提高其独立
性)。耦合性存在于各个领域,而非软件设计中独有的,但是我们只讨论软件工程中的耦合。
在软件工程中,耦合指的就是就是对象之间的依赖性。对象之间的耦合越高,维护成本越高。因此对象的设计
应使类和构件之间的耦合最小。软件设计中通常用耦合度和内聚度作为衡量模块独立程度的标准。 划分模块的一个
准 则就是高内聚低耦合。
工厂模式的解耦
- 什么是工厂模式
工厂顾名思义就是创建产品,根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。该模式用于封装和管理对象的创建,是一种创建型模式 - 我们以往的3层架构 dao service controller 之间咋样引用的
dao层
public class AccountDaoImpl implements IAccountDao{
public void saveAccount() {
System.out.println("保存了账户");
}
}
service层
public class AccountServiceImpl implements IAccountService {
// 都要通过new 关键字 去创建对象
private IAccountDao accountDao = new AccountDaoImpl();;
public void saveAccount() {
accountDao.saveAccount();
}
}
controller
IAccountService as = new AccountServiceImpl();
as.saveAccount();
缺点
- 代码耦合度高,不易于维护
- 我们使用工厂模式根据不同的参数生产出不同的类
- 一个创建bean对象工厂 :使用工厂模式进行解耦; 编译时不会报错,运行时报错
- Bean: 在计算机英语中,有可重用组件的含义
- JavaBean: 用java语音编写的可重复有组件
javabean > 实体类
- 创建我们的service和dao 对象
- 需要一个配置文件来配置我们的servie和dao
配置内容: 唯一标识==全限定类名 (key == value)
- 通过读取配置文件配置内容,反射创建对象
- 我们配置文件xml,properties, maven工程 配置文件放入resources目录下。
- 我们创建一个工厂类文件BeanFactory
public class BeanFactory {
//定义一个Properties对象
private static Properties props;
//使用静态代码块为Properties对象赋值
static {
try {
//实例化对象
props = new Properties();
//获取properties文件流对象, 不要使用new FileInputStream(),使用类加载器不要考虑路径问题。
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
props.load(in);
} catch (IOException e) {
e.printStackTrace();
}
}
//根据bean的名称获取bean对象
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;
}
}
- bean.properties 配置文件:目的配置对应的 全限定类名映射关系
accountService = com.itheima.service.impl.AccountServiceImpl
accountDao = com.itheima.dao.impl.AccountDaoImpl
- service层 引用dao层改写
public class AccountServiceImpl implements IAccountService {
//通过工厂模式
private IAccountDao accountDao = (IAccountDao) BeanFactory.getBean("accountDao");
public void saveAccount() {
accountDao.saveAccount();
}
}
- controller层 引用 service层 改写
// IAccountService as =(IAccountService) BeanFactory.getBean("accountService");
// as.saveAccount();
// 验证多例模式 单例模式
for(int i = 0; i < 5; i ++) {
IAccountService as =(IAccountService) BeanFactory.getBean("accountService");
System.out.println(as);
as.saveAccount();
}
多例模式.png
缺点
- 每次调用都会生成新的对象,影响性能
工厂模式-单例模式
我们创建一个工厂类文件BeanFactory
public class BeanFactory2 {
//定义一个Properties对象
private static Properties props;
//定义一个map对象, 用于存放我们能要创建的对象,我们称之为容器
private static Map<String, Object> beans;
//使用静态代码块为Properties对象赋值
static {
try {
//实例化对象
props = new Properties();
//获取properties文件流对象, 不要使用new FileInputStream(),使用类加载器不要考虑路径问题。
InputStream in = BeanFactory2.class.getClassLoader().getResourceAsStream("bean.properties");
props.load(in);
//实例化容器
beans = new HashMap<String, Object>();
//取出配置文件的key
Enumeration<Object> keys = props.keys();
//遍历枚举
while (keys.hasMoreElements()) {
//取出每一key
String key = keys.nextElement().toString();
//根据key获取value
String beanPath = props.getProperty(key);
//反射创建对象,意思就是根据beanPath 动态创建对象
Object value = Class.forName(beanPath).newInstance();
//把key和value 存放到容器;
beans.put(key,value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//根据bean的名称获取bean对象
public static Object getBean(String beanName) {
return beans.get(beanName);
}
单例模式.png
spring的控制翻反转Inversion Of Control(IOC)
理解:当我们使用其他的类的引用,我们可以使用new关键字,去得到想要的类,这种模式 主动权在自己手里;通过工厂模式把想要得到类,权力转移了给工厂,通过配置文件找到我们想要的类,从而降低类与类之间的依赖关系,从而降低了耦合。
注意 只是削减计算机程序的耦合(解除我们代码中的依赖关系)。
整体架构图
spring的IOC
ioc.png
网友评论