一、概述:
工厂模式就是专门负责将大量有共同接口的类实例化,而且不必事先知道每次是要实例化哪一个类的模式。它定义一个用于创建对象的接口,由子类决定实例化哪一个类。
二、简单工厂模式的结构:
三、简单的实例:
1.定义一个接口,代表一类Javabean
public interface UserDao {
public void save();
}
2.定义UserDao的实现类:
public class UserDaoWithMySql implements UserDao{
public void save(){
System.out.println("mysql save");
}
}
public class UserDaoWithOracle implements UserDao{
public void save(){
System.out.println("Oracle Save!");
}
}
3.定义用来产生UserDao的工厂:
/**
* 用来产生UserDao的工厂
* @author yu
*
*/
public class UserDaoFactory {
public static UserDao create(){
// return new UserDaoWithMySql();
return new UserDaoWithOracle();
}
}
4.测试:
UserDao ud = UserDaoFactory.create();
ud.save();
使用的时候要获取不同的实现类,只需要改变UserDaoFactory的返回值就行了,但还是显得不够灵活,且看下面的例子:
四、会延迟加载Bean的BeanFactory:
1.定义一个properties文件:bean.properties:
mysql=com.cxy.factory.simple.UserDaoWithMySql
oracle=com.cxy.factory.simple.UserDaoWithOracle
2.定义BeanFactory(BeanFactory_lazy):
package com.cxy.factory.simple;
import java.io.IOException;
import java.util.Properties;
public class BeanFactory_lazy {
private static Properties pro;
static{
pro = new Properties();
try {
//读取properties文件
pro.load(BeanFactory_lazy.class.getClassLoader().getResourceAsStream("bean.properties"));
} catch (IOException e) {
e.printStackTrace();
}
}
public static UserDao getBean(String key){
if(pro.containsKey(key)){
String className = pro.getProperty(key);
try {
return (UserDao) Class.forName(className).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}else{
throw new IllegalArgumentException();
}
}
}
3.测试:
UserDao ud = BeanFactory_lazy.getBean("oracle");
ud.save();
实际应用中可以根据需要给getBean()方法传入不同的参数,即可获取不同的Bean
上面的代码中,虽然实现了灵活的获取Bean的方法,但是只有在用到Bean的时候才会实例化对应的Bean,有时候我们想让初始化BeanFactory的时候就将配置的Bean都创建好,且看下面的代码:
4.非延迟加载的BeanFactory
package com.cxy.factory.simple;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Map.Entry;
public class BeanFactory {
private static Properties pro;
//用来存放properties文件中的信息
private static Map<String,Object> map = new HashMap<String, Object>();
static{
pro = new Properties();
try {
pro.load(BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties"));
} catch (IOException e) {
e.printStackTrace();
}
//迭代该properties文件,将其内容读入到map中
for(Entry<Object ,Object> entry : pro.entrySet() ){
String key = (String) entry.getKey();
String className = (String) entry.getValue();
try {
Object userDao = Class.forName(className).newInstance();
map.put(key, userDao);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
public static UserDao getBean(String key){
if(map.containsKey(key)){
return (UserDao) map.get(key);
}else{
throw new IllegalArgumentException();
}
}
}
将实例化Bean的步骤放在static静态块内,那么在实例化该类之前就会创建所有的Bean对象,在用到的时候直接拿就可以了
上面的代码是Spring中BeanFactory的简单实现,只不过Spring使用的是Xml配置文件,这个到无所谓,原理最重要,实现途径倒是其次