java设计模式-创建型模式-建造者模式
场景举例
根据表名、每页条数、偏移量等属性进行拼接组装,并且根据不同的数据库类型生成不同的sql脚本
观察Lombok @Builder注解生成的代码
源码
java
package xin.yangshuai.basic01.gof23.builder;
import lombok.Builder;
@Builder
public class DatabaseSqlLombok {
/**
* 数据库类型
*/
private String database;
/**
* 表名
*/
private String tableName;
/**
* 每页条数
*/
private Integer pageSize;
/**
* 偏移量
*/
private Integer offset;
/**
* sql
*/
private String sql;
}
编译后的代码(反编译回java代码)
java
package xin.yangshuai.basic01.gof23.builder;
public class DatabaseSqlLombok {
private String database;
private String tableName;
private Integer pageSize;
private Integer offset;
private String sql;
DatabaseSqlLombok(String database, String tableName, Integer pageSize, Integer offset, String sql) {
this.database = database;
this.tableName = tableName;
this.pageSize = pageSize;
this.offset = offset;
this.sql = sql;
}
public static DatabaseSqlLombokBuilder builder() {
return new DatabaseSqlLombokBuilder();
}
public static class DatabaseSqlLombokBuilder {
private String database;
private String tableName;
private Integer pageSize;
private Integer offset;
private String sql;
DatabaseSqlLombokBuilder() {
}
public DatabaseSqlLombokBuilder database(String database) {
this.database = database;
return this;
}
public DatabaseSqlLombokBuilder tableName(String tableName) {
this.tableName = tableName;
return this;
}
public DatabaseSqlLombokBuilder pageSize(Integer pageSize) {
this.pageSize = pageSize;
return this;
}
public DatabaseSqlLombokBuilder offset(Integer offset) {
this.offset = offset;
return this;
}
public DatabaseSqlLombokBuilder sql(String sql) {
this.sql = sql;
return this;
}
public DatabaseSqlLombok build() {
return new DatabaseSqlLombok(this.database, this.tableName, this.pageSize, this.offset, this.sql);
}
public String toString() {
return "DatabaseSqlLombok.DatabaseSqlLombokBuilder(database=" + this.database + ", tableName=" + this.tableName + ", pageSize=" + this.pageSize + ", offset=" + this.offset + ", sql=" + this.sql + ")";
}
}
}
建造者模式中的几种角色
产品(Product)
具体的产品
抽象建造者(Builder)
定义创建产品各个部件的方法,通常包括多个创建产品部件的方法和一个返回具体产品的方法
具体建造者(ConcreteBuilder)
实现抽象建造者的接口
指挥者(Director)
控制建造者创建产品各个部件的顺序
代码示例
参考lombok生成的代码,定义建造者模式中的各个角色
产品:DatabaseSql
java
package xin.yangshuai.basic01.gof23.builder;
public class DatabaseSql {
/**
* 数据库类型
*/
private String database;
/**
* 表名
*/
private String tableName;
/**
* 每页条数
*/
private Integer pageSize;
/**
* 偏移量
*/
private Integer offset;
/**
* sql
*/
private String sql;
public DatabaseSql() {
}
public DatabaseSql(String database, String tableName, Integer pageSize, Integer offset, String sql) {
this.database = database;
this.tableName = tableName;
this.pageSize = pageSize;
this.offset = offset;
this.sql = sql;
}
public String getDatabase() {
return database;
}
public void setDatabase(String database) {
this.database = database;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getOffset() {
return offset;
}
public void setOffset(Integer offset) {
this.offset = offset;
}
public String getSql() {
return sql;
}
public void setSql(String sql) {
this.sql = sql;
}
}
抽象建造者:DatabaseSqlBuilder
java
package xin.yangshuai.basic01.gof23.builder;
public interface DatabaseSqlBuilder {
/**
* 数据库类型
*
* @return
*/
DatabaseSqlBuilder database();
/**
* 表名
*
* @param tableName
* @return
*/
DatabaseSqlBuilder tableName(String tableName);
/**
* 每页条数
*
* @param pageSize
* @return
*/
DatabaseSqlBuilder pageSize(Integer pageSize);
/**
* 偏移量
*
* @param offset
* @return
*/
DatabaseSqlBuilder offset(Integer offset);
/**
* sql
*
* @return
*/
DatabaseSqlBuilder sql();
/**
* 生成DatabaseSql
*
* @return
*/
DatabaseSql build();
}
具体建造者:MySQLDatabaseSqlBuilder
java
package xin.yangshuai.basic01.gof23.builder;
public class MySQLDatabaseSqlBuilder implements DatabaseSqlBuilder {
/**
* 数据库类型
*/
private String database;
/**
* 表名
*/
private String tableName;
/**
* 每页条数
*/
private Integer pageSize;
/**
* 偏移量
*/
private Integer offset;
/**
* sql
*/
private String sql;
@Override
public DatabaseSqlBuilder database() {
this.database = "MySQL";
return this;
}
public DatabaseSqlBuilder tableName(String tableName) {
this.tableName = tableName;
return this;
}
public DatabaseSqlBuilder pageSize(Integer pageSize) {
this.pageSize = pageSize;
return this;
}
public DatabaseSqlBuilder offset(Integer offset) {
this.offset = offset;
return this;
}
@Override
public DatabaseSqlBuilder sql() {
this.sql = "select * from " + tableName + " limit " + offset + "," + pageSize + ";";
return this;
}
@Override
public DatabaseSql build() {
return new DatabaseSql(database, tableName, pageSize, offset, sql);
}
}
指挥者:DatabaseSqlDirector
java
package xin.yangshuai.basic01.gof23.builder;
public class DatabaseSqlDirector {
private DatabaseSqlBuilder databaseSqlBuilder;
public void setDatabaseSqlBuilder(DatabaseSqlBuilder databaseSqlBuilder) {
this.databaseSqlBuilder = databaseSqlBuilder;
}
public DatabaseSql build(){
if (databaseSqlBuilder != null) {
return databaseSqlBuilder.database().sql().build();
}
return null;
}
}
方法调用测试
java
package xin.yangshuai.basic01.gof23.builder;
public class Main {
public static void main(String[] args) {
DatabaseSqlBuilder databaseSqlBuilder = new MySQLDatabaseSqlBuilder().tableName("test_user").offset(0).pageSize(10);
DatabaseSqlDirector databaseSqlDirector = new DatabaseSqlDirector();
databaseSqlDirector.setDatabaseSqlBuilder(databaseSqlBuilder);
DatabaseSql databaseSql = databaseSqlDirector.build();
System.out.println(databaseSql.getDatabase());
System.out.println(databaseSql.getSql());
}
}
响应信息
log
MySQL
select * from test_user limit 0,10;
个人理解
- 指挥者的作用:设置比较复杂的属性,比如上面例子中设置sql属性(需要其它属性进行组合,拼接),可能需要指挥者类来控制执行的顺序
- 一般情况应该不需要指挥者类
如有不对,欢迎指正!