设计模式探索:建造者模式

1. 什么是建造者模式

建造者模式 (Builder Pattern),也被称为生成器模式,是一种创建型设计模式。

  • 定义:将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式要解决的问题:

  • 建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。用户只需要指定复杂对象的类型就可以得到该对象,而无需知道其内部的具体构造细节。
    在这里插入图片描述

2. 建造者模式的结构

在这里插入图片描述

建造者(Builder)模式包含以下4个角色:

  1. 抽象建造者类(Builder):规定要实现复杂对象的哪些部分的创建,并不涉及具体的部件对象的创建。
  2. 具体建造者类(ConcreteBuilder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。在构造过程完成后,提供一个方法,返回创建好的复杂产品对象。
  3. 产品类(Product):要创建的复杂对象 (包含多个组成部件)。
  4. 指挥者类(Director):调用具体建造者来创建复杂对象的各个部分,在指挥者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建(客户端一般只需要与指挥者进行交互)。

3. 代码示例

下面是一个SQL查询生成器的例子,展示如何使用建造者模式生成不同数据库的SQL查询语句。

产品类
public class SqlQuery {
    private String select;
    private String from;
    private String where;
    private String groupBy;
    private String orderBy;
    private String limit;

    public SqlQuery(String select, String from) {
        this.select = select;
        this.from = from;
    }

    // Getters and setters

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("SELECT ").append(select).append(" FROM ").append(from);

        if (where != null && !where.isEmpty()) {
            sb.append(" WHERE ").append(where);
        }

        if (groupBy != null && !groupBy.isEmpty()) {
            sb.append(" GROUP BY ").append(groupBy);
        }

        if (orderBy != null && !orderBy.isEmpty()) {
            sb.append(" ORDER BY ").append(orderBy);
        }

        if (limit != null && !limit.isEmpty()) {
            sb.append(" LIMIT ").append(limit);
        }

        return sb.toString();
    }
}

抽象建造者

public abstract class SqlQueryBuilder {
    protected SqlQuery sqlQuery;

    public void createSqlQuery(String select, String from) {
        sqlQuery = new SqlQuery(select, from);
    }

    public SqlQuery getSqlQuery() {
        return sqlQuery;
    }

    public abstract void buildWhere();
    public abstract void buildGroupBy();
    public abstract void buildOrderBy();
    public abstract void buildLimit();
}

具体建造者

public class MySqlQueryBuilder extends SqlQueryBuilder {
    @Override
    public void buildWhere() {
        sqlQuery.setWhere("1 = 1"); // MySQL不需要限制行数
    }

    @Override
    public void buildGroupBy() {
        sqlQuery.setGroupBy("deptno, ename, hiredate");
    }

    @Override
    public void buildOrderBy() {
        sqlQuery.setOrderBy("hiredate DESC");
    }

    @Override
    public void buildLimit() {
        sqlQuery.setLimit("0, 10"); // MySQL分页从0开始
    }
}

public class OracleQueryBuilder extends SqlQueryBuilder {
    @Override
    public void buildWhere() {
        sqlQuery.setWhere("rownum <= 1000"); // Oracle查询最多返回1000行数据
    }

    @Override
    public void buildGroupBy() {
        sqlQuery.setGroupBy("deptno, ename, hiredate");
        sqlQuery.setSelect(sqlQuery.getSelect() + ", deptno, ename, hiredate");
    }

    @Override
    public void buildOrderBy() {
        sqlQuery.setOrderBy("hiredate");
    }

    @Override
    public void buildLimit() {
        sqlQuery.setLimit("10");
    }
}

指挥者类

public class SqlQueryDirector {
    private SqlQueryBuilder sqlQueryBuilder;

    public void setSqlQueryBuilder(SqlQueryBuilder sqlQueryBuilder) {
        this.sqlQueryBuilder = sqlQueryBuilder;
    }

    public void buildSqlQuery(String select, String from) {
        sqlQueryBuilder.createSqlQuery(select, from);
        sqlQueryBuilder.buildWhere();
        sqlQueryBuilder.buildGroupBy();
        sqlQueryBuilder.buildOrderBy();
        sqlQueryBuilder.buildLimit();
    }
}

客户端

public class Client {
    public static void main(String[] args) {
        // 创建MySQL建造者
        SqlQueryBuilder mySqlQueryBuilder = new MySqlQueryBuilder();

        // 创建Oracle建造者
        SqlQueryBuilder oracleQueryBuilder = new OracleQueryBuilder();

        // 指导者
        SqlQueryDirector sqlQueryDirector = new SqlQueryDirector();

        // 构建MySQL查询语句
        sqlQueryDirector.setSqlQueryBuilder(mySqlQueryBuilder);
        sqlQueryDirector.buildSqlQuery("*", "table1");

        SqlQuery mySqlQuery = mySqlQueryBuilder.getSqlQuery();
        System.out.println("MySQL Query: " + mySqlQuery);

        // 构建Oracle查询语句
        sqlQueryDirector.setSqlQueryBuilder(oracleQueryBuilder);
        sqlQueryDirector.buildSqlQuery("*", "table2");
        SqlQuery oracleQuery = oracleQueryBuilder.getSqlQuery();
        System.out.println("Oracle Query: " + oracleQuery);
    }
}

4. 建造者模式在实际开发中的应用

建造者模式在实际开发中的应用主要体现在以下几个方面:

  1. 复杂对象的创建:例如,在创建一个复杂对象时,如果这个对象有很多可选参数,使用建造者模式可以避免构造函数参数列表过长的问题。
  2. 多步骤创建过程:例如,在构建SQL查询、创建报告等需要多个步骤的过程中,使用建造者模式可以将这些步骤分离出来,使得代码更易于维护和扩展。
  3. 对象的不变性:例如,创建一个不可变对象时,可以使用建造者模式来确保对象在创建后不被修改。

5. 建造者模式与工厂模式的区别

  1. 工厂模式

    • 用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象。
    • 主要关注的是创建单个对象。
      在这里插入图片描述
  2. 建造者模式

    • 用来创建一种类型的复杂对象,通过设置不同的可选参数,“定制化”地创建不同的对象。
    • 主要关注的是如何一步一步创建一个复杂的对象。
    • 更强调创建过程的分步和顺序。
      在这里插入图片描述

总之,建造者模式可以很好地解决创建复杂对象时的代码复用性和可维护性问题,而工厂模式则更加适用于创建一组相关的对象。

  • 19
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搬砖的小熊猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值