工厂设计模式
Spring本质:工厂
Spring提供的工厂是ApplicationContext (配置文件 application.xml)
1.概念:通过工厂类创建对象
2.好处:解耦合
耦合:指代码间的强关联关系,乙方的改变会影响到另一方,不利于代码维护。简单来说就是把接口的实现类硬编码在程序中。如下程序段:
User user = new User();
UserDao userDao = new UserDaoImpl();
1.简单工厂的设计
package com.ypz;
/**
* @author :ypz
* @date :2020/7/18 14:04
* @description:TODO
*/
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* @author ypz
* @date 2020/7/18 14:04
*/
public class BeanFactory {
//创建Properties集合env
private static Properties env = new Properties();
/*
* IO是系统级资源,尽量避免重复打开IO
* 最好是在程序启动时一次性读取想要的内容,使用静态代码块
* */
//读取配置文件内容
static{
try {
//1.获得IO输入流
InputStream inputStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties");
//2.文件内容封装到Properties集合中
env.load(inputStream);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 创建对象的方式:
* 1.直接调用构造方法 UserService userService = new UserServiceImlp();
* 2.通过反射的形式创建对象 解耦合
* Class clazz = Class.forName("com.ypz.UserServiceImpl");
* UserService userService = (UserService)clazz.newInstance();
*/
public static UserService getUserService(){
// return new UserServiceImpl();
UserService userService = null;
try {
// Class clazz = Class.forName("com.ypz.UserServiceImpl"); //此时并不能完全解耦,全限定名如果改变还是要改工厂代码 解决:将全限定名放进properties文件
Class clazz = Class.forName(env.getProperty("userService"));
userService = (UserService)clazz.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return userService;
}
public static UserDao getUserDao(){
UserDao userDao = null;
try {
Class clazz = Class.forName(env.getProperty("userDao"));
userDao = (UserDao)clazz.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return userDao;
}
}
2.通用工厂的设计
简单工厂工厂存在大量代码冗余,每次要创建一个新的对象都需要写一个getxxx方法
package com.ypz;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class BeanFactory {
//创建Properties集合env
private static Properties env = new Properties();
/*
* IO是系统级资源,尽量避免重复打开IO
* 最好是在程序启动时一次性读取想要的内容,使用静态代码块
* */
//读取配置文件内容
static {
try {
//1.获得IO输入流
InputStream inputStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties");
//2.文件内容封装到Properties集合中
env.load(inputStream);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @Description: 工厂通用方法 用它创建一切想要创建的对象
* @Param: [key] 配置文件中的key [userDao,userService]
* @return: java.lang.Object
* @author: Mrs.You
* @Date: 2020-07-20
*/
public static Object getBean(String key) {
Object ret = null;
try {
Class clazz = Class.forName(env.getProperty(key));
ret = clazz.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return ret;
}
}
3.通用工厂的使用方式
1. 定义(创建)类型(类)
2. 通过配置文件的配置告知工厂(applicationContext.properties)
key = value
3. 通过工厂获得类的对象
Object ret = BeanFactory.getBean("key")