工厂模式Demo

工厂模式:

      工厂模式:用于程序间的解耦合。

       耦合:程序间的直接相互调用

初级工厂

//BeanFactory.class
public class BeanFactory {

    public static ICustomerService getCustomerService(){
	    try {
		    return (ICustomerService) Class.forName("com.layman.Service.Impl.ICustomerServiceImpl").newInstance();
    	} catch (Exception e) {
    		throw new RuntimeException(e);
    	} 
	}

	public static ICustomerDao getCustomerDao(){
		try {
			return (ICustomerDao) Class.forName("com.layman.Dao.Impl.CustomerDaoImpl").newInstance();		
    	}catch (Exception e) {
			throw new RuntimeException(e);
		} 
	}
}

//Client.class 
public class Client {
    public static void main(String[] args) {
    	//使用反射的方式
	    ICustomerService service = BeanFactory.getCustomerService();
	    service.saveCustomer();
    }
    
}

//CustomerDaoImpl.class
public class CustomerDaoImpl implements ICustomerDao {

@Override
public void saveCustomer() {
	// TODO Auto-generated method stub
	System.out.println("持久层保存用户");
}
}
  • 这个就是使用反射的机制 来实例化对象。而不是使用new的方式。

上面所写虽然耦合解开 但是每个对象的获取都需要一个get方法

  • 解决方式:使用properties配置文件。

中级工厂

//perproties配置文件
CUSTOMERSERVICE=com.layman.Service.Impl.ICustomerServiceImpl
CUSTOMERDAO=com.layman.Dao.Impl.CustomerDaoImpl

//BeanFactory.java

public class BeanFactory {
    //1.定义一个properties对象
    private static Properties props = new Properties();

    //2.使用静态代码块给对象赋值
    static{
        try{
            InputStream in =BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
        props.load(in);
        }catch(Exception e){
            throw new ExceptionInInitializerError("读取配置文件失败"+ e);
        }
    }
}

public static Object getBean(String beanName) {
	try {
		// 1.读取配置文件,跟beanName获取全限定类名
		String beanPath = props.getProperty(beanName);
		return Class.forName(beanPath).newInstance();
	} catch (Exception e) {
		throw new RuntimeException(e);
	}
}

//Client.class 
public class Client {
    public static void main(String[] args) {
	//使用反射的方式
    ICustomerService service = BeanFactory.getBean("CUSTERMERSERVICE");
    service.saveCustomer();
    }
}
  • 这样就解决了每个类都需要get方法的弊端。
  • 这是一个不错的方法,使用了输入流和类加载器。但是存在一个更加简单的方法:使用ResourceBundle类

高级版

public class BeanFactory {
    // 1.只能用于读取properties文件,别的读不了
    // 2.只能用于读取,不能用于写入
    // 3.只能读取类加路径下的,不在类路径下读取不了
    // 4.方法参数的写法是 包名+文件名(不需要扩展名)
	private static ResourceBundle bundle =     ResourceBundle.getBundle("bean");

    	public static Object getBean(String beanName) {
    	try {
			// 1.读取配置文件,跟beanName获取全限定类名
			String beanPath = bundle.getString(beanName);
			return Class.forName(beanPath).newInstance();
		} catch (Exception e) {
    		throw new RuntimeException(e);
		}
		return beans.get(beanName);
	}
}

public static Object getBean(String beanName) {
	try {
		// 1.读取配置文件,跟beanName获取全限定类名
		String beanPath = bundle.getString(beanName);
		return Class.forName(beanPath).newInstance();
	} catch (Exception e) {
		throw new RuntimeException(e);
	}
}
  • 创建一个ResourceBundle类,使用它的静态方法getBundle(fileName);来读取配置文件,但是不可以写入,且文件必须要在类路径下,因为它是基于classLoader实现的。
  • 这样的工厂模式虽然很好,但是在每一次调用getBean(String beanName)方法的时候都会重新创建一个bean对象。
  • 解决方案:使用Map<String,Object>。来提前遍历bean.perporties文件,并创建对应的对象。getBean(String beanName)方法直接返map中的对象。

终极版

public class BeanFactory{
    // 1.只能用于读取properties文件,别的读不了
    // 2.只能用于读取,不能用于写入
    // 3.只能读取类加路径下的,不在类路径下读取不了
    // 4.方法参数的写法是 包名+文件名(不需要扩展名)
	private static ResourceBundle bundle = ResourceBundle.getBundle("bean");

    // 定义一个容器,用来存放我们要使用的对象
    private static Map<String, Object> beans = new HashMap<String, Object>();

    // 使用静态代码块初始化map
    static {
    	// 1.读取配置文件中所有的配置:key部分
	    Enumeration<String> keys = bundle.getKeys();
    // 2.遍历keys
	try {
		while (keys.hasMoreElements()) {
			// 3.取出一个key
			String key = keys.nextElement();
			// 4.根据key获取beanPath
			String beanPath = bundle.getString(key);
			// 5.根据beanPath反射创建类对象
			Object value = Class.forName(beanPath).newInstance();
			// 6.把key和value存入map中
			beans.put(key, value);
		}
	} catch (Exception e) {
		// TODO Auto-generated catch block
		throw new ExceptionInInitializerError("容器创建失败,停止执行");
	}
}

public static Object getBean(String beanName) {
	return beans.get(beanName);
}
  • 使用ResourceBundle对象来读取配置文件,然后创建使用的容器,接着使用静态代码块来遍历keys并实例化对象。最后getBean(String beanName) 所返回的就是map容器中的对象,这样所有的线程都是使用的同一个对象。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值