JSP学习笔记(第3次):基于配置文件与反射的工厂模式

原创 2016年08月28日 16:49:55

1.两种普通的工厂模式分析

1.1 简单的工厂模式

这里写图片描述
通过一个工厂(工厂类)接受订单(参数),从而判断制造哪种产品(对象
如以下代码:

public static Operation createOperate(string operate)
{
    Operation oper = null;
    switch (operate)
    {
        case "A":
            {
            oper = new OperationA();
            break;
            }
        case "B":
            {
            oper = new OperationB();
            break;
            }
    }
    return oper;
}
}

1.2一般工厂模式

专门工厂,一对一实现生产
这里写图片描述
如下面代码:

/*接口类*/
public interface IFactoryDao {
    public IUserDao createUserDao();
    public IAddressDao createAddressDao();
}

/*实现类*/
/*JDBC工厂*/
public class JDBCDaoFactory implements IFactoryDao {
    private static JDBCDaoFactory factory = new JDBCDaoFactory();
    /*
     * 限制new
     */
    private JDBCDaoFactory(){}

    public static IFactoryDao getInstance() {
        return factory;
    }

    @Override
    public IUserDao createUserDao() {
        return new UserJDBCDao();
    }

    @Override
    public IAddressDao createAddressDao() {
        return new AddressJDBCDao();
    }

}

/*Oracal工厂*/
public class OracleDaoFactory implements IFactoryDao {
    private static IFactoryDao f = new OracleDaoFactory();
    private OracleDaoFactory(){}

    public static IFactoryDao getInstance() {
        return f;
    }
    @Override
    public IUserDao createUserDao() {
        return new UserOracleDao();
    }

    @Override
    public IAddressDao createAddressDao() {
        return new AddressOracleDao();
    }

}

/*MySQL工厂*/
package itat.zttc.shop.dao;

public class MysqlDaoFactory implements IFactoryDao {
    private static IFactoryDao factory = new MysqlDaoFactory();
    private MysqlDaoFactory() { }

    public static IFactoryDao getInstance() {
        return factory;
    }

    @Override
    public IAddressDao createAddressDao() {
        return new AddressMysqlDao();
    }

    @Override
    public IUserDao createUserDao() {
        return new UserMysqlDao();
    }
}

1.3简单工厂和专门工厂的缺点

以上两种方法如果在小程序中,代码不需要怎么变动,写完就结束的情况下还可以接受。

但是现假设:

假设1:
我现在要在以上简单工厂所属的程序中加入一个新的操作类—-OperatorC.

于是我得修改源代码,直接对工厂类做内科手术,显然违背了OCP(一个软件实体如类、模块和函数应该对扩展开放,对修改关闭)。

假设2:
现在我要对一般工厂所属程序中加入新数据库连接类AddressSqlserverDao和UserSqlserverDao,如此一来我不在修改IFactory代码,只需增加一个SqlserverDaoFactory类,但是这种方式只是把我的代码修改转移给了客户端而已。

2.基于配置文件和反射的工厂模式

从上两种假设而知的解决缺陷可知,上两种工厂都不完美,都需要动手术才能完成原程序对新类的接受,那么,如何来做可以来避免手术发生?

联想到字符串创建类,我们可以很容易联想到反射和配置文件方式,把数据写在配置文件中,从配置文件中读取字符数据,然后通过反射就可以不通过外科手术方式来实现对内部调用的修改。

2.1建立一个工具类以获取配置文件数据

import java.io.IOException;
import java.util.Properties;

public class PropertiesUtil {
    private static Properties jdbcProp;
    private static Properties daoProp;

    public static Properties getJdbcProp() {
        try {
            if(jdbcProp==null) {
                jdbcProp = new Properties();
                jdbcProp.load(PropertiesUtil.class.getClassLoader().getResourceAsStream("jdbc.properties"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return jdbcProp;
    }

    public static Properties getDaoProp() {
        try {
            if(daoProp==null) {
                daoProp = new Properties();
                daoProp.load(PropertiesUtil.class.getClassLoader().getResourceAsStream("dao.properties"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return daoProp;
    }
}

2.2实现公厂模式

//接口IFactoryDao
public interface IFactoryDao {
    public Object getDao(String name);//addressDao
}

//单例模式实现类
public class PropertiesFactory implements IFactoryDao {
    private static PropertiesFactory f = new PropertiesFactory();
    //创建一个散列来保存已经查找过的键对,减少访问外部配置文件的速度
    private static Map<String,Object> daos = new HashMap<String, Object>();

    //私有化构造方法以实现单例模式
    private PropertiesFactory() {   }

    //得到单例
    public static IFactoryDao getInstance() {
        return f;
    }

    //实现接口中的getDao
    @Override
    public Object getDao(String name) {
        try {
            /*验证键值对是否已经存在于单例中的散列中,在则直接返回值,不访问外部配置文件以加快访问速度*/
            if(daos.containsKey(name)){
                return daos.get(name);
            }
            //利用工具类PropertiesUtil获取配置文件数据
            Properties prop = PropertiesUtil.getDaoProp();

            //通过数据名获取配置文件中的数据
            String cn = prop.getProperty(name);

            //反射方法来构造对象并存于散列中,这样就实现了在配置文件中的文本数据来控制程序内部的逻辑
            Object obj = Class.forName(cn).newInstance();
            daos.put(name, obj);
            return obj;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

}

3.总结

反射在JAVA的各种框架中都有使用,利用反射可以让代码变得更简单更灵活,在各种场合下反射的利用是一剂良药,免去了很多大手术,大切除的下策。

版权声明:本文为博主原创文章,未经博主允许不得转载。

JSP&Servlet学习笔记(2): 编写与设置Servlet

第一个Servlet程序 package cc.openhome; import java.io.IOException; import java.io.PrintWriter; impor...
  • hxllhhy
  • hxllhhy
  • 2017年12月19日 00:47
  • 59

工厂模式基于properties配置文件

工厂模式的概念就不讨论了,本文介绍一种通过
  • xjh2011xjh
  • xjh2011xjh
  • 2014年05月11日 13:56
  • 904

汇编语言作业

程序2:补全程序,计算   assume cs:code,ds:data data  segment    x db  45h    y db  ? data  ends   code...
  • L_dream_2016
  • L_dream_2016
  • 2017年05月08日 20:09
  • 270

基于C#反射机制的工厂模式

简介反射提供了描述程序集、模块和类型的对象(Type 类型)。可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。如果代码中使用了特性,可以利用反...
  • qp120291570
  • qp120291570
  • 2016年04月09日 19:11
  • 3514

工厂模式(使用配置文件来确定具体的实例)

通过配置文件来确定具体生成哪个实例 1,接口: package com.it.design; public interface Sender { void send(Strin...
  • liu537192
  • liu537192
  • 2014年12月24日 17:00
  • 592

基于Spring注解实现工厂模式

前面看到了南寒之星的一篇文章,地址:https://my.oschina.net/u/923324/blog/832269,通过自己写扫描java文件的类来自动注入工厂模式中接口的实现类。 然后今天想...
  • zzpzheng
  • zzpzheng
  • 2017年05月16日 20:23
  • 1721

一个例子穿插三种不同的工厂模式形态

1、简单工厂模式 工厂类根据提供给它的参数,返回的是几个产品中的一个类的实例。通常情况下,它返回的是一个公共的父类,在这个工厂类里面,父类的引用指向子类的对象 厂长生产杯子时先不让生产线知道我...
  • u013360022
  • u013360022
  • 2016年04月07日 21:59
  • 611

OpenCV.Resize详解

详解opencv.resize函数,在各个图像处理项目里都应用十分广泛。最近一个小作业,整理图片大小不一样的数据集,就把它详细学习了一下。...
  • kokozeng1995
  • kokozeng1995
  • 2017年11月14日 20:38
  • 37

《Servlet与JSP核心编程第二版》阅读记录002-第一个servlet示例程序

1 新建目录,用于保存相关练习代码     D:\java_project\servlet_practice 保存整个练习过程代码的根目录     D:\java_project\servlet_pr...
  • aben06
  • aben06
  • 2015年08月26日 15:19
  • 635

JSP-tomcat中配置web应用程序

JSP-tomcat中配置web应用程序 在JSP的学习中,我们利用开发工具Myeclipse建立一个新的WEB项目是很简单的,但是我们如果不用工具怎么手动配置一个web项目呢?下面我就位大家讲解一...
  • liu1028701143
  • liu1028701143
  • 2011年10月13日 07:59
  • 380
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JSP学习笔记(第3次):基于配置文件与反射的工厂模式
举报原因:
原因补充:

(最多只允许输入30个字)