设计模式(工厂方法模式的概述和使用)
* A:工厂方法模式概述
* 工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现。
* B:优点
* 客户端不需要在负责对象的创建,从而明确了各个类的职责,如果有新的对象增加,只需要增加一个具体的类和具体的工厂类即可,不影响已有的代码,后期维护容易,增强了系统的扩展性
* C:缺点
* 需要额外的编写代码,增加了工作量
* D:案例演示
*
动物抽象类:public abstract Animal { public abstract void
eat(); }
工厂接口:public interface Factory {public abstract Animal
createAnimal();}
具体狗类:public class Dog extends Animal {}
具体猫类:public class Cat extends Animal {}
开始,在测试类中每个具体的内容自己创建对象,但是,创建对象的工作如果比较
麻烦,就需要有人专门做这个事情,所以就知道了一个专门的类来创建对象。发现每次修改代码太麻烦,用工厂方法改进,针对每一个具体的实现提供一个具体工厂。
狗工厂:public class DogFactory implements Factory {
public
Animal createAnimal() {…}
}
猫工厂:public class CatFactory implements Factory {
public
Animal createAnimal() {…}
}
javaweb中的应用
public interface BeanFactory {
public Object getBean(String name);
}
/**
* 修改此类为单利模式 使用饿汉式
* 1.构造方法为private
* 2.成员变量直接实例化
* @author lenovo
*
*/
/**
* 修改此类为单利模式 使用饿汉式
* 1.构造方法为private
* 2.成员变量直接实例化
* @author lenovo
*
*/
public class PropertiesBeanFactory implements BeanFactory{
private Map<String,Object> dao= new HashMap<String, Object>();
public Object getBean(String name) {
// TODO 传进来从dao缓存中直接取出来以后使用反射直接实例化
return dao.get(name);
}
//要在web应用加载得时候就实例化此工厂
public PropertiesBeanFactory(String configrationFile){
try {
Properties pro = new Properties();//这个是一个map集合
pro.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(configrationFile));
Set entrySet = pro.entrySet();
//从集合中取出来 在放入dao缓存集合中
for (Iterator iterator = entrySet.iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
String key = (String) entry.getKey();//dao的名称
String className = (String) entry.getValue();//dao得具体包
Class clz= Class.forName(className);//反射
Object bean = clz.newInstance();//把每个Dao都实例化好了
dao.put(key, bean);//把DAO的实现类对象放到集合缓存起来
}
} catch (Exception e) {
e.printStackTrace();
}
}
public PropertiesBeanFactory(){
this("beans.properties");
}
}
那么如何实例化呢
public class InitBeanFactory extends HttpServlet {
/**
* Initialization of the servlet. <br>
*@主要是为了把为了在web应用加载的时候就初始化PropertiesBeanFactory
* @throws ServletException if an error occurs
*/
public static final String INIT_FACTORY_NAME="_my_bean_factory";//application
@Override
public void init(ServletConfig config) throws ServletException {
//从配置文件里面取configLocation bean.properties
String configLocation = config.getInitParameter("configLocation");//beans.properties从配置文件中拿到配置文件得名字
PropertiesBeanFactory factory = null;
//判断如果没有获得字符串
if(configLocation==null){
factory = new PropertiesBeanFactory();
}else{
factory = new PropertiesBeanFactory(configLocation);
}
//获得servletContext 放到servletContext里面
config.getServletContext().setAttribute(INIT_FACTORY_NAME, factory);
//初始化类型转换器 当遇到set就会调用转换器ChannelsSetConverter
ConvertUtils.register(new ChannelsSetConverter(),Set.class);
System.out.println("initBeanfactory调用了web应用加载了");
}
}
web.xml中的配置
<servlet>
<servlet-name>InitBeanFactory</servlet-name>
<servlet-class>cn.com.leadfar.cms.backend.view.InitBeanFactory</servlet-class>
<init-param>
<param-name>configLocation</param-name>
<param-value>beans.properties</param-value>
</init-param>
<load-on-startup>0</load-on-startup>启动级别
</servlet>
在servlet中的调用方式 可以放在servlet根据设计方法编写
//取出的是PropertiesBeanFactory对象 从servletContext里面取出初始化时放入的factory
BeanFactory factory = (BeanFactory) getServletContext().getAttribute(InitBeanFactory.INIT_FACTORY_NAME);
//通过反射来拿到子类得方法集合
Method[] methods = this.getClass().getMethods();
//取到子类startswith(set)的方法数组
for (Method m : methods) {

浙公网安备 33010602011771号