带参数的工厂模式

时间:2017-05-25 23:20:07

标签: java design-patterns

我正在为我的log4j输出使用JDBC连接器,并希望将我的日志条目发布到Postgres数据库。这看起来如下:

<Jdbc name="Jdbc" tableName="log">
    <ConnectionFactory class="database.ConnectionFactory" method="getConnection"/>
    <Column name="event_date" isEventTimestamp="true" />
    <Column name="level" pattern="%level" isUnicode="false" />
    <Column name="logger" pattern="%logger" isUnicode="false" />
    <Column name="message" pattern="%message" isUnicode="false" />
     <Column name="exception" pattern="%ex{full}" isUnicode="false" />
</Jdbc>

据我所知,这需要一个方法为getConnection的静态类,我使用工厂模式实现了这个:

public class ConnectionFactory {
    private static interface Singleton {
        final ConnectionFactory INSTANCE = new ConnectionFactory();
    }

    private ComboPooledDataSource comboPooledDataSource;

    private ConnectionFactory() {
        comboPooledDataSource = new ComboPooledDataSource();
        try {
            // Load the jdbc driver.
            comboPooledDataSource.setDriverClass("org.postgresql.Driver");
        } catch (PropertyVetoException exception) {

        }

        // Need to create datasource here, requires parameters.
    }

    public static Connection getConnection() throws SQLException {
        return Singleton.INSTANCE.comboPooledDataSource.getConnection();
    }
}

我的问题是,我想通过参数(主机,端口,数据库等)创建与数据库的连接,并且不想对其进行硬编码。还有一个保持配置的静态类不是首选,因为我希望能够轻松地进行单元测试。

实现这一目标的好方法是什么?我可能会忽视某些事情或这是一种不好的做法吗?

2 个答案:

答案 0 :(得分:1)

工厂方法可以采用参数。

答案 1 :(得分:-1)

使用反射和枚举可以帮助: 我已经为自己实现了类似的东西:

public class BusFactory {

public IBus createBus(BusType busType, String busUrl) {

    try {

        if(busType == null){
            return null;
        }

        //Touraj: Get Bus By Reflection

        Class<?> busClass = Class.forName(busType.getFullQualifiedName());
        Constructor con = busClass.getConstructor(String.class);

        Object busObj = con.newInstance(busUrl);

        if (busObj instanceof ETCDBus) {

            return (ETCDBus)busObj;

        } else if (busObj instanceof AeroSpikeBus) {

            return (AeroSpikeBus)busObj;

        }else
        {
            throw new UnsupportedBusException("this Type of Bus is not Supported");
        }

    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (UnsupportedBusException e) {
        e.printStackTrace();
    }

    return null;
}
}

和BusType是这样的:

public enum BusType {

ETCD("BUS.ETCDBus"),
AEROSPIKE("AEROSPIKE"),
RAIMA("RAIMA"),
HANA("HANA"),
GEODE("GEODE"),
IGNITE("IGNITE"),
SENTINEL("SENTINEL"),
REDIS("BUS.RedisBus"),
Informix("Informix");

private String fullQualifiedName;

BusType(String fullQualifiedName) {
    this.fullQualifiedName = fullQualifiedName;
}

public String getFullQualifiedName() {
    return fullQualifiedName;
}

}