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

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

工厂模式的代码实现,简单易懂。

工厂模式的代码实现,简单易懂。 interface fruit { public abstract void eat(); } class Apple implements fruit { ...

设计模式学习之抽象工厂模式(二)<反射+配置文件>

接上一篇文章《设计模式学习之抽象工厂模式(实现数据访问层)》继续学习,抽象工厂模式,本文在上一篇文章(对应程序为1.0,本文对应的程序为2.0版本)的基础之上上进行了改进。当然程序也升级为2.0版本啦...

抽象工厂模式+反射+配置文件

 配置文件+抽象工厂+反射 1 题目分析: 利用抽象工厂,实现数据库程序访问系统。使用配置文件加反射的方法。 2 UML:   3 代码: using System; usin...

利用“工厂模式+反射+配置文件”来实现解耦和

我们在利用java的三层架构开发时,如果用Web层直接创建service层,然后再用service层直接创建dao层 ,这样的话如果我们底层的实现类发生了变化,我们就要去修改源代码了,这很显然不是很符...

工厂模式基于properties配置文件

工厂模式的概念就不讨论了,本文介绍一种通过

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

通过配置文件来确定具体生成哪个实例 1,接口: package com.it.design; public interface Sender { void send(Strin...

java反射机制+工厂模式+配置文件----->在谈到spring配置文件

下面的程序是从魔乐科技java教程里面抄来的,感觉这几段程序说明了一些问题,所以就抄过来了。 下面是一个简单的工厂模式  package org; interface Fruit{ ...

Java学习笔记----工厂模式和反射

C#课上老师讲的工厂模式和反射,做了些笔记,课下自己结合JAVA,再复习一次工厂模式还有反射。 工厂模式,顾名思义,工厂是负责生产产品的。我们把代码分成两大块,一块是工厂,一块是客户。 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JSP学习笔记(第3次):基于配置文件与反射的工厂模式
举报原因:
原因补充:

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