工厂模式
工厂模式是我们最常用的实例化对象模式,是用工厂方法替代new操作的一种模式,著名的jive论坛,就大量使用了工厂模式,工厂模式在java程序系统可以说是随处可见。因为工厂模式就相当于创建实例对象的new。我们经常要根据类生成实例对象,如A a= new A()工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做写工作,但会给你的系统带来更大的可扩展性和尽量少的修改量。
实现步骤:
1. 私有化一个工厂类对象
2.私有化构造器 //不给外部创建对象,保持对象的唯一性,单例
3.通过静态代码块初始化对象
4.提供一个静态共有的方法把工厂对象返回出去
1 1 public class FactoryTest { 2 2 3 3 //1.创建一个私有的工厂对象 4 4 private static FactoryTest factoryTest; 5 5 //2.私有化构造器 6 6 7 7 private FactoryTest() { 8 8 } 9 9 10 10 //3.静态代码块中初始化对象 11 11 12 12 static { 13 13 14 14 factoryTest = new FactoryTest(); 15 15 16 16 17 17 } 18 18 //4.提供一个静态方法返回该对象 19 19 public static FactoryTest getFactoryTest(){ 20 20 21 21 return factoryTest; 22 22 } 23 23 24 public CustomterDao getCustomterDaoImpl(){ 25 26 27 return new CustomterDaoImpl(); 28 } 29 30 24 }
第一种方式 直接创建dao层对象
第二种方式 通过工厂模式创建单个对象
但是这样的工厂模式是强依赖的,三层之间强耦合的,并且只能创建单个对象,无法创建多个对象,更不能指定创建对象
1. 通过工厂类BeanFactory,创建客户Dao实现类对象,消除了客户service与客户dao实现类的直接依赖关系
2. 但是这里并没有消除应用程序,与客户dao实现类的直接依赖关系,只是从客户service,转移到工厂类
3. 并且此时工厂类BeanFactory,只能创建客户一个对象,别的对象创建不了
第三种模式 工厂升级版
对上面进行升级
使用配置文件,配置三层的对象,dao,service实现类。在工厂类中,通过加载配置文件,根据配置文件内容,使用反射技术运行时创建对象。
1 /** 2 * 工厂类对象 3 */ 4 public class BeanFactory { 5 6 // 1.声明私有的工厂类对象引用 7 private static BeanFactory beanFactory; 8 9 // 2.把构造方法私有化 10 private BeanFactory(){ 11 12 } 13 14 // 使用Properties API加载属性资源文件 15 private static Properties prop; 16 17 // 3.使用静态代码块初始化 18 static { 19 beanFactory = new BeanFactory(); 20 21 // 初始化Properties加载属性资源文件 22 prop = new Properties(); 23 24 InputStream inputStream = BeanFactory.class 25 .getClassLoader().getResourceAsStream("bean.properties"); 26 try { 27 prop.load(inputStream); 28 } catch (IOException e) { 29 e.printStackTrace(); 30 } 31 } 32 33 // 4.提供一个公有的静态的方法,获取工厂类对象引用 34 public static BeanFactory getBeanFactory(){ 35 return beanFactory; 36 } 37 38 /** 39 * 创建客户dao对象 40 */ 41 /*public CustomerDao getCustomerDao(){ 42 return new CustomerDaoImpl(); 43 }*/ 44 45 /** 46 * 工厂类创建对象:改良版本 47 */ 48 public Object getBean(String beanName){ 49 Object obj = null; 50 51 // 根据beanName获取配置文件中的全限定类名称 52 String className = prop.getProperty(beanName); 53 54 // 通过反射技术,调用无参数构造方法创建对象 55 try{ 56 obj = Class.forName(className).newInstance(); 57 }catch(Exception e){ 58 System.out.println("实例化对象失败:"+className); 59 e.printStackTrace(); 60 } 61 62 return obj; 63 } 64 }
1 // 从工厂类改良版本getBean方法获取客户dao对象 2 private CustomerDao customerDao = (CustomerDao) BeanFactory.getBeanFactory() 3 .getBean("CUSTOMERDAO");
1 // 从工厂类改良版本getBean方法,获取客户service对象 2 CustomerService customerService = (CustomerService) BeanFactory.getBeanFactory() 3 .getBean("CUSTOMERSERVICE");
1.1.1. 工厂模式解耦理解
说明:
在实际项目开发中,我们可以通过配置文件把controller、service、dao对象配置起来,当启动服务器加载应用的时候,读取配置文件,创建配置文件中的对象并且保存起来。在接下来实际使用的地方,直接拿过来使用即可。此时我们需要考虑两个问题:
将对象存放在什么地方?
由于在一个应用中,会需要大量的对象,首先考虑的是使用集合Map或者List来存储对象。那么这里选择Map还是List,需要考虑我们有没有查找需求,有则选择Map。
此处我们的选择是:在应用加载时候,创建一个Map,用于存放controller、service、dao对象。这个Map我们把它称为容器。
什么是工厂呢?
工厂就是负责创建对象,并且把对象放到容器中。并且在使用的时候,帮助我们从容器获取指定的对象。此时我们获取对象的方式发生了改变。
原来: 我们获取对象时,都是采用new的方式。是主动获取
现在: 我们获取对象时,找工厂要,由工厂创建并且提供给我们。是被动接收
结论:
这种将创建对象的权利,由在程序代码中主动new对象的方式,转变为由工厂类创建提供,我们使用的地方被动接收的方式。称为控制反转。控制反转也叫IOC(Inversion Of Control)
在这里我们首先明确一个事情:spring的IOC解决的问题,即是工厂模式解耦解决的问题。
第四种 IOC的方式
不需要依赖dao层创建对象 ,解耦了,各层直接都是通过配置文件(IOC)容器创建对象,因此ioc解决了,工厂模式不能创建多个对象和解耦问题