设计模式之简单工厂及工厂方法

1.简单工厂
(1)产品抽象类:

    protected final Vertx vertx;
    protected final String tenantId;
    private static long explainQueryThreshold;
    public SqlClient(Vertx vertx, String tenantId) throws Exception {
        this.tenantId = tenantId;
        this.vertx = vertx;
        explainQueryThreshold = 1000L;
    }

    public abstract void closeClient(Handler<AsyncResult<Void>> whenDone);

    public abstract void execute(String sql, Handler<AsyncResult<RowSet<Row>>> replyHandler);

    public abstract void execute(String sql, Tuple params, Handler<AsyncResult<RowSet<Row>>> replyHandler);
    //其他方法省略...

(2)具体产品类1

public class SqlServerClient extends  SqlClient{

    private static String configPath = null;
    protected static final Logger log = LoggerFactory.getLogger(SqlServerClient.class);
    private static MultiKeyMap<Object, SqlServerClient> connectionPool = MultiKeyMap.multiKeyMap(new HashedMap());
    private MSSQLPool client;
    private JsonObject postgreSQLClientConfig = null;
    private static final String STATS_KEY = SqlServerClient.class.getName();
    private static ObjectMapper mapper = ObjectMapperTool.getMapper();
    private static long explainQueryThreshold;
    public SqlServerClient(Vertx vertx, String tenantId) throws Exception {
    super(vertx,tenantId);
    init();
    }


    public static String getConfigFilePath() {
        if (configPath == null) {
            configPath = "/sqlserver-conf.json";
        }
        return configPath;
    }


    public void init() throws Exception {
        this.postgreSQLClientConfig = getSsmConfig(null);
        this.client = createMSSqlPool(vertx, this.postgreSQLClientConfig);
    }


    static JsonObject getSsmConfig( JsonObject environmentVariables)  {
        JsonObject config = environmentVariables;
        if (environmentVariables!=null&&environmentVariables.size() > 0) {
            log.info("DB config read from environment variables");
        } else {
            config = LoadConfs.loadConfig(getConfigFilePath());
        }
        if (config == null) {
            config = new JsonObject();
            config.put("username", "username");
            config.put("password", "password");
            config.put("host", "127.0.0.1");
            config.put("port", 6000);
            config.put("database", "postgres");
        }


        return config;
    }


 //方法省略...

}

(3)具体产品2

public class  PostgresClient extends SqlClient{
    private static String configPath = null;
    protected static final Logger log = LoggerFactory.getLogger(PostgresClient.class);
    private static MultiKeyMap<Object, PostgresClient> connectionPool = MultiKeyMap.multiKeyMap(new HashedMap());
    private PgPool client;
    private JsonObject postgreSQLClientConfig = null;
    private static final String STATS_KEY = PostgresClient.class.getName();
    private static ObjectMapper mapper = ObjectMapperTool.getMapper();
    private static long explainQueryThreshold;
    public PostgresClient(Vertx vertx, String tenantId) throws Exception {
     super(vertx,tenantId);
    init();
    }

    public static String getConfigFilePath() {
        if (configPath == null) {
            configPath = "/postgres-conf.json";
        }


        return configPath;
    }
    private void init() throws Exception {
//        this.postgreSQLClientConfig = getPostgreSQLClientConfig(Envs.allDBConfs());
        //todo 环境变量有bug
        this.postgreSQLClientConfig = getPostgreSQLClientConfig(null);
        this.client = createPgPool(this.vertx, this.postgreSQLClientConfig);
    }
//方法省略...
}

(4)静态工厂方法

public class PostgresClientFactory {

  public static PostgresClient getInstance(Vertx vertx, Map<String, String> okapiHeaders) {
    return PostgresClient.getInstance(vertx, TenantTool.tenantId(okapiHeaders));
  }
  public static PostgresClient getInstance(Vertx vertx, String tenantId) {
    return PostgresClient.getInstance(vertx, tenantId);
  }

}

对于工厂方法,需要再抽象工厂方法,并将静态的创建实例改为非静态的。

public abstract class SqlClientFactory {

    public abstract  SqlClient getInstance(Vertx vertx, Map<String, String> okapiHeaders) ;
    public abstract SqlClient getInstance(Vertx vertx, String tenantId);
}

//也可以使用接口


public interface SqlClientFactory {

    public SqlClient getInstance(Vertx vertx, Map<String, String> okapiHeaders) ;
    public SqlClient getInstance(Vertx vertx, String tenantId);
}

实例工厂方法1

public class PostgresClientFactory extends SqlClientFactory{
  @Override
  public  PostgresClient getInstance(Vertx vertx, Map<String, String> okapiHeaders) {
    return PostgresClient.getInstance(vertx, TenantTool.tenantId(okapiHeaders));
  }


  @Override
  public  PostgresClient getInstance(Vertx vertx, String tenantId) {
    return PostgresClient.getInstance(vertx, tenantId);
  }

}

实例工厂方法2

public class SqlServerClientFactory extends SqlClientFactory{
  @Override
  public  SqlServerClient getInstance(Vertx vertx, Map<String, String> okapiHeaders) {
    return SqlServerClient.getInstance(vertx, TenantTool.tenantId(okapiHeaders));
  }


  @Override
  public  SqlServerClient getInstance(Vertx vertx, String tenantId) {
    return SqlServerClient.getInstance(vertx, tenantId);
  }
}

注:根据多态,调用的接口只能是抽象接口中有的接口,实际接口是具体的产品。
抽象工厂对比工厂方法,抽象工厂与工厂方法的角色一样,但是抽象工厂方法是是针对一族产品

抽象工厂:

public abstract class SqlClientFactory {

    public abstract  SqlClient getInstance(Vertx vertx, Map<String, String> okapiHeaders) ;
    public abstract SqlClient getInstance(Vertx vertx, String tenantId);
     //其他产品,省略...

}


//也可以使用接口


public interface SqlClientFactory {


    public SqlClient getInstance(Vertx vertx, Map<String