設計模式系列之工廠模式

設計模式之工廠模式

工廠模式包括了簡單工廠、工廠方法和抽象工廠。下面我從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

相關文章
相關標籤/搜索