设计模式系列之工厂模式

设计模式之工厂模式

工厂模式包括了简单工厂、工厂方法和抽象工厂。下面我从java实际应用的角度分别介绍这三种模式。java

简单工厂模式

下面看下JDBC中获取Connection的代码mysql

public class ConnectionFactory {
    public Connection createConnection(String dbType,String serverName,String dbName,String userName,String password) throws SQLException
    {
        if(dbType.equalsIgnoreCase("mysql"))
        {
            try 
            {
                Class.forName("com.mysql.cj.jdbc.Driver");
            } catch (ClassNotFoundException e) 
            {
                throw new RuntimeException(e);
            }
            String url = "jdbc:mysql://"+serverName+":3306/"+dbName
                    +"?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT";
            return DriverManager.getConnection(url,userName,password);
        }
        else if(dbType.equalsIgnoreCase("postgresql"))
        {
            try 
            {
                Class.forName("org.postgresql.Driver");
            } catch (ClassNotFoundException e) 
            {
                throw new RuntimeException(e);
            }
            String url = "jbdc:postgresql://"+serverName+":5432/"+dbName;
            return DriverManager.getConnection(url,userName,password);
        }
        else if(dbType.equalsIgnoreCase("MariaDB"))
        {
            try 
            {
                Class.forName("org.mariadb.jdbc.Driver");
            } catch (ClassNotFoundException e) 
            {
                throw new RuntimeException(e);
            }
            String url = "jdbc:mariadb://"+serverName+":3306/"+dbName;
            return DriverManager.getConnection(url,userName,password);
        }
        else
        {
            throw new IllegalArgumentException("未知的dbType参数类型");
        }
    }
}

这段代码中就使用了简单工厂模式。咱们传入不一样的参数类型,工厂内部就会建立不一样的对象实例,咱们根本不用管工厂内部的实现逻辑是什么。
缺点:违背设计原则:对扩展开放,对修改关闭。由于假如我业务须要新增一个数据库Connection 获取方式就得修改这部分的代码。sql

工厂方法模式

下面咱们针对普通工厂模式的缺点进行优化。
咱们能够定义一个工厂方法接口IConnectionFactory ,包含一个方法,交给子类去实现各自的Connection建立方法数据库

public interface IConnectionFactory {
    Connection create(String serverName,String dbName,String userName,String password) throws SQLException;
}

建立PostgreSqlConnectionFactory工厂并实现IConnectionFactory接口设计模式

public class PostgreSqlConnectionFactory implements IConnectionFactory {

    @Override
    public Connection create(String serverName, String dbName, String userName, String password) throws SQLException {
        try 
        {
            Class.forName("org.postgresql.Driver");
        } catch (ClassNotFoundException e) 
        {
            throw new RuntimeException(e);
        }
        String url = "jbdc:postgresql://"+serverName+":5432/"+dbName;
        return DriverManager.getConnection(url,userName,password);
    }

}

建立MySqlConnectionFactory 工厂并实现IConnectionFactory接口ide

public class MySqlConnectionFactory implements IConnectionFactory {

    @Override
    public Connection create(String serverName, String dbName, String userName, String password) throws SQLException {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        String url = "jdbc:mysql://" + serverName + ":3306/" + dbName
                + "?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT";
        return DriverManager.getConnection(url, userName, password);
    }

}

建立MariaDBConnectionFactory 工厂并实现IConnectionFactory接口post

public class MariaDBConnectionFactory implements IConnectionFactory {

    @Override
    public Connection create(String serverName, String dbName, String userName, String password) throws SQLException {
        try 
        {
            Class.forName("org.mariadb.jdbc.Driver");
        } catch (ClassNotFoundException e) 
        {
            throw new RuntimeException(e);
        }
        String url = "jdbc:mariadb://"+serverName+":3306/"+dbName;
        return DriverManager.getConnection(url,userName,password);
    }

}

测试方法测试

Connection conn = new MySqlConnectionFactory().create("127.0.0.1", "test", "root", "root");

工厂方法模式的优势:新增一种类型,只需增长一个工厂,并实现抽象工厂便可。
缺点就是调用者须要知道调用的子类对象对应的子类工厂。优化

抽象工厂

上述的一个工厂对应一个产品,若是一个工厂对应多个产品那就是咱们的抽象工厂模式了。好比 Connection 接口就是应用了抽象工厂模式。其中的方法都是工厂方法,好比:createStatement、prepareStatement、prepareCall等他们都有对应的实现类。url

相关文章
相关标签/搜索