工厂模式

      工厂模式是我们最常用的实例化对象模式,是用工厂方法替代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解决了,工厂模式不能创建多个对象和解耦问题

 

 

posted @ 2020-06-06 15:06  JAVA_宇  阅读(192)  评论(0编辑  收藏  举报