参考的学习视频→https://b23.tv/av47952931/p82
◆传统方式
我们创建一个maven工程(不选择任何骨架),在pom文件中添加<packaging>jar</packaging>标签,设置打包方式为jar
新建IAccountService接口,在此接口内写一个用来模拟保存账户的方法
新建一个IAccountDao接口作为账户的持久层接口,仍然写一个方法来模拟账户保存的操作
新建一个AccountDaoImpl类继承IAccountDao接口,并实现该接口的saveAccount()方法(这里用打印一个字符串代替)
新建一个AccountServiceImpl类继承IAccountService接口作为账户的业务层实现类
新建一个Client类模拟表现层,在这里编写main函数来调用业务层,运行工程,程序正常运行
但是此代码的不足之处在于有很强的耦合性(因为用了new的方式创建对象,一旦删掉了某一个类,代码就无法正常编译)
◆下面用工厂模式来解决耦合的问题
~首先了解一些知识~
Bean:在英语中,有可重用组件的含义
JavaBean:用java语言编写的可重用组件
JavaBean > 实体类
- 作用:创建service和dao对象
- 实现方法:
- 需要一个配置文件来配置 service和dao
- 通过读取配置文件中的内容来反射创建对象
▶配置内容:唯一标识=全限定类名(key=value) ◀▶配置文件类型:xml或properties ◀
于是我们新建一个BeanFactory类,用来创建Bean
创建bean.properties文件并配置参数,我们把com.example.service.impl.AccountServiceImpl 和com.example.dao.impl.AccountDaoImpl这两个类作为参数写在了配置文件中
在BeanFactory中定义一个Properties对象,使用静态代码块为Properties对象赋值,并定义一个static方法返回根据名称获取的Bean
修改Client类的main方法,将new对象改为反射的方式创建对象
同样地,修改AccountServiceImpl类
点击运行,程序正常运行
这时如果我们再删除掉AccountDaoImpl这个类
再次运行,程序仍然编译通过,只是在运行时抛出无法找到类的异常
◆分析工厂模式存在的问题并修改
为了说明问题,我们在Client类的main方法中加入一个for循环,一共取出5个Bean并打印它们的内存首地址。运行程序,发现它们的首地址各不相同
这说明此时的对象是多例的,也就是说每次getBean都创建了一个新的对象,这是因为getBean方法中,newInstance()方法每次都会调用默认构造函数创建对象
如果需要创建单例对象(即对象只被创建一次,从而类中的成员只会初始化一次,每次get到的都是同一个对象),就必须把创建的对象存起来,于是我们定义一个map用于存放我们要创建的对象,我们把它称之为容器
我们在静态代码块中根据配置文件中的所有key分别反射创建对象,然后存入Map中
这样一来,我们的getBean方法只用将容器中对应的Bean返回即可
运行程序,我们发现打印出5次获得的Bean的首地址相同,说明该对象是单例的