此处对工厂模式的分析目的是为了更好地理解Spring IOC
一、程序的耦合
耦合,这里可以简单的理解为:程序间的依赖。
常见的耦合包括:类之间的耦合、方法间的耦合。
解耦:降低程序间的依赖关系。
在实际开发中应该做到:编译期间不依赖,运行期间才依赖。
public class AccountServiceImpl implements IAccountService {
private IAccountDao accountDao = new AccountDaoImpl();
}
上面的代码表示: 业务层调用持久层,并且此时业务层在依赖持久层的接口和实现类。如果此时没有持久层实现类,编译将不能通过。这种编译期依赖关系,应该在我们开发中杜绝。我们需要优化代码解决。
解耦思路:
第一步:使用反射来创建对象,避免使用new关键字。
第二步:通过读取配置文件来获取要创建的对象的全限定类名
二、工厂模式解耦
在实际开发中我们可以把三层的对象都使用配置文件配置起来,当启动服务器应用加载的时候,让一个类中的方法通过读取配置文件,把这些对象创建出来并存起来。在接下来的使用的时候,直接拿过来用就好了。 那么,这个读取配置文件,创建和获取三层对象的类就是工厂。
这里使用的是Properties配置文件,存放的是获取对象时的唯一标志和全限定类名(也就是基于xml配置方式实现ioc时,bean标签的两个属性)。
这里简单说一下为什么要保存起来,这是因为java的垃圾回收机制,长时间不使用会被回收。在这种情况下并不一定能保证单例。
采用工厂模式,不保存情况下的代码如上。
那么,如果保存的话,应该保存到那里?
分析:由于我们是很多对象,肯定要找个集合来存。这时候有Map和List供选择。 到底选Map还是List就看我们有没有查找需求。有查找需求,选Map。 所以我们的答案就是 在应用加载时,创建一个Map,用于存放三层对象。 我们把这个map称之为容器。
对工厂模式进行改造如下:
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); }
三、new关键字的主动模式和工厂被动模式
我们在获取对象时,都是采用new的方式。是主动的。
我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象。是被动的。
这种被动接收的方式获取对象的思想就是控制反转,它是spring框架的核心之一。
明确ioc的作用: 削减计算机程序的耦合(解除我们代码中的依赖关系)。
来源:CSDN
作者:清风不灭
链接:https://blog.csdn.net/weixin_40391011/article/details/104177990