乐趣区

关于java:Java设计模式之工厂方式

在剖析工厂模式之前,咱们先看看一般模式下的 Java 三层构造。

Controller(体现层)-Service(业务层)-Dao(长久层、数据库连贯层), 基于此三层构造实现 JavaWeb 相干业务。
假如咱们要实现的业务是增加员工信息,
先创立 Dao 包,创立 EmpDao 接口和 EmpDaoFactory 实现类。Dao 包构造.png

package com.yd.dao;
/**
 *     员工模块 Dao(长久层)接口
 *
 */
public interface EmpDao {
    //    增加员工信息
    public void addEmp();}
package com.yd.dao;
/**
 *     员工模块 Dao(长久层)接口实现类
 *
 */
public class EmpDaoImpl implements EmpDao{public void addEmp() {System.out.println("Dao 层的 addEmp()办法执行了..");
    }
}

再创立 Service 包,创立 EmpService 接口和 EmpServiceImpl 实现类,在实现类中创立 Dao 接口的子类对象,这样做是程序之间的耦合性回升。

package com.yd.service;
/**
 *     员工模块的 service(业务层)接口
 *
 */
public interface EmpService {
    //    增加员工信息
    public void addEmp();}
package com.yd.service;

import com.yd.dao.EmpDao;
import com.yd.dao.EmpDaoImpl;

/**
 *     员工模块的 service(业务层)接口实现类
 *
 */
public class EmpServiceImpl implements EmpService{
    
    // 调用 Dao 接口的子类对象
    //new 对象使程序之间的耦合性回升
    private EmpDao dao=new EmpDaoImpl();
    
    public void addEmp() {System.out.println("调用 dao 层的办法增加员工信息");
        
    }

}

最初创立 controller 包,在包中创立 EmpController 类

package com.yd.controller;

import org.junit.Test;

import com.yd.service.EmpService;
import com.yd.service.EmpServiceImpl;

/**
 *     模仿体现层
 *     controller-> service-> dao
 *
 */
public class EmpController {
    
    /**
     *     获取 service 接口的子类实例
     *     new 对象造成程序耦合性回升
     */
    //EmpService 成员变量手动属性注入,属性注入了一个 EmpServiceImpl 对象。private EmpService service=new EmpServiceImpl();
    
    @Test
    public void testAddEmp() {System.out.println("调用 service 层的办法增加员工信息");
        service.addEmp();}

}

咱们能够发现,在 EmpServiceImpl 类中创立了 EmpDaoImp 类的对象,两个类之间的耦合性回升;在 EmpController 类中创立了 EmpSericeImpl 对象,两个类之间的耦合性回升。
间接 new 对象使程序的耦合性回升,为日后的保护降级带来麻烦。

工厂形式解耦,完满解决了模块之间的耦合性过高的问题。
工厂模式,顾名思义,就是建设一个对象工厂,利用工厂来创立每个实现类的对象。就像工厂生产手机、电脑等工业品一样,这个工厂什么对象都能造!
在革新以上代码之前,先理解一些概念。
bean: 可重用组件
JavaBean:java 语言编写的可重用组件,例如 service 层,dao 层,Controller 层。
bean 分为业务 bean 和实体 bean。
业务 bean: 解决业务逻辑,service 层和 Dao 层
实体 bean: 封装数据,相当于 mvc 设计模式的 model、POJO,本人编写的 Emp 实体类。

如何解耦?

  1. 提供配置文件,在配置文件中配置 service 和 dao 的实现类
  2. 通过工厂读取配置文件中的全限定类名,利用反射创建对象,如.properties 和.xml 文件

革新下面的代码,第一步:创立一个 Factory 包和 BeanFatory 类。

package com.yd.Factory;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class BeanFactory {
    
    // 申明一个 Properties 对象,在动态代码块中初始化
    private static Properties prop;
    static {
        
        //prop 实例化
        prop = new Properties();
        // 获取配置流对象,失去配置文件的内容
        InputStream inputStream = BeanFactory.class.getClassLoader().getResourceAsStream("config.properties");
        
        try {
            // 将配置文件中的内容读到 Prop 对象中
            prop.load(inputStream);
        } catch (IOException e) {e.printStackTrace();
            throw new RuntimeException("初始化 properties 对象失败");
        }
    }
    
    /**
     *     依据 config.xml 文件中的 key 获取对应的 class 类实例
     *     @param key
     *     @return bean
     */
    public static Object getBean(String key) {
        Object bean=null;
        try {
            // 失去 key 对应的 value 值,并创建对象
            String className = prop.getProperty(key);
            bean = Class.forName(className).newInstance();} catch (Exception e) {e.printStackTrace();
        }
        return bean;
    }
}

在以上代码中,首先申明了 properies 类的对象 prop,利用反射机制(ClassName.class)和 ClassLoader 类加载器中的 getResourceAsStream(),将配置文件以流的模式读取进去,prop 加载此流的信息,读取到配置文件。
prop 对象依据传入 key 获取对应的 value,value 就是类的全限定类名,依据此类名利用反射机制创立想要对象。并返回给调用者。

第二步:在根目录下创立 config.properies 文件

EmpService=com.yd.service.EmpServiceImpl
EmpDao=com.yd.dao.EmpDaoImpl

第三步:在 EmpController 类中增加如下代码

    // 工厂形式解耦
    // 获取 Service 接口的子类实例
    private EmpService service=(EmpService) BeanFactory.getBean("EmpSerice");
    // 获取 Dao 接口的子类实例
    private EmpDao empDao=(EmpDao) BeanFactory.getBean("EmpDao");
    
    @Test
    public void testAddEmp() {System.out.println("工厂形式调用 service 层的办法增加员工信息");
        service.addEmp();}
    

工厂模式实质就是利用 Java 的反射机制和 ClassLoader 类加载器,为开发者提供一个创立类的对立接口。开发者只须要调用 Beanfactory(),配合.properties 文件,就能创立实例,调用办法。
基于工厂模式,大佬和高手开发出了弱小的工具 spring 和 springboot,spring 以 IOC(Inverse Of Control:管制反转)和 AOP(Aspact Oriented Programming:面向切面编程)为外围,整合开源世界的大多数第三方框架,成为应用最多的 JavaEE 企业应用开源框架。
spring 的实质就是管理程序的对象,即创建对象和保护对象之间的关系。

退出移动版