1. 工厂模式
1.1. 概述
在Action里面,我们要调用CustomerDao的login方法,传统情况你用什么代码?
CustomerDao cdao = new CustomerDao(): cdao.login(); |
1.2. 考虑以下情况
l 如果cdao实例对象前,需要做一些准备工作,如:判断数据是否连接
l 如果该Action以后可以切换到另一个StudentDao,也调用login方法。
l 如何让Action开发人员只需要知道要实例哪个对象,而不需要知道如何实例化对象?
1.3. 解决方法:使用工厂模式
1.3.1. 创建接口
创建一个接口,定义一个方法login,那么所以子类都要实现该方法。例如:
interface ICustomerDao{ public abstract void login(); }
class CustomerDao implements ICustomerDao{ public void login(){ System.out.println("Dao 登陆"); } } |
1.3.2. 创建工厂类
根据工厂类,可以切换子类。例如:
class DaoFactory{ public static Object getDao(String daoName){ if(daoName.equals("Customer")){
return new CustomerDao(); } //else if(/*...*/){ } //return null; } } |
当然可以根据反射机制来进一步的优化,根据传过来的类的全路径,进行生成对象。代码如下:
class DaoFactory{ public static Object getDao(String className){ //根据配置文件获取className对应的类名,如果切换, 改变配置文件中对应的类名就可以了 return Class.forName(className).newInstance(); } } |
1.4. 工厂模式要点
l 用接口将需要实例化的类管理起来
l 开发工厂类,编写创建方法,传入参数,工厂类根据客户端传入参数决定实例化哪个对象,返回。
l 可以利用反射来降低耦合性
1.5. 工厂模式小结
l 客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。
l 缺点是当产品修改时,工厂类也要做相应的修改。怎样克服?Spring可以克服
l 工厂模式主要应用于模块间调用时模块可调用接口较多的情况;实例化一个对象可能要进行复杂操作的情况
l 练习:有一个复杂的Frame,一个复杂的Jframe,现在客户传入参数1、2来决定得到Frame还是Jframe,要求客户不关心Frame和Jframe的生成过程,怎么设计?