建造者模式 – 设计模式之创建模式

建造者模式 – 设计模式之创建模式:

 

目录

定义:

类图:

StringBuilder:

SqlSessionFactoryBuilder 

应用场景一:多个参数查询拼接

订单查询参数类:OrderParam

订单查询参数测试类: OrderParamBuilderTest

请求参数拼接 OrderController

总结:


 

定义:

    Separate the construction of a complex object from its representation so that the same construction process can create different representations.

建造者模式(Builder Pattern)是将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示,属于创建型模式。使用建造者模式对于用户而言只需指定需要建造的类型就可以获得对象,建造过程及细节不需要了解

 

类图:

 

建造者模式通用类图:

 

 

在学习建造者模式的时候,我一直没有联想到实际具体可以操作的实例。不过有StringBuilder 可以看看,学习下实际中具体的应用。

 

StringBuilder

 部分代码:

public final class StringBuilder

    extends AbstractStringBuilder

    implements java.io.Serializable, CharSequence

{
@Override

public StringBuilder append(Object obj) {

    return append(String.valueOf(obj));

}



@Override

public StringBuilder append(String str) {

    super.append(str);

    return this;

}

public StringBuilder append(StringBuffer sb) {

    super.append(sb);

    return this;

}



@Override

public StringBuilder append(CharSequence s) {

    super.append(s);

    return this;

}

@Override

public StringBuilder append(char[] str) {

    super.append(str);

    return this;

}


@Override

public StringBuilder append(boolean b) {

    super.append(b);

    return this;

}



@Override

public StringBuilder append(char c) {

    super.append(c);

    return this;

}



@Override

public StringBuilder append(int i) {

    super.append(i);

    return this;

}



@Override

public StringBuilder append(long lng) {

    super.append(lng);

    return this;

}



@Override

public StringBuilder append(float f) {

    super.append(f);

    return this;

}



@Override

public StringBuilder append(double d) {

    super.append(d);

    return this;

}

}

 在使用的时候,我们可以append各种类型的数据。这种实现还是很强大的。

 public static void main(String[] args) {

    StringBuilder stringBuilder = new StringBuilder();

    String s = stringBuilder.append(1L).append("y").append(3.0D).append(9.9F).append("px").toString();

    System.out.println(s);

}

 

SqlSessionFactoryBuilder 

mybatis 中的建造者模式

我们来看 org.apache.ibatis.session 包下的 SqlSessionFactoryBuilder 类

比如版本: 'org.mybatis:mybatis:3.5.1'
public class SqlSessionFactoryBuilder {

  public SqlSessionFactory build(Reader reader) {
    return build(reader, null, null);
  }

  public SqlSessionFactory build(Reader reader, String environment) {
    return build(reader, environment, null);
  }

  public SqlSessionFactory build(Reader reader, Properties properties) {
    return build(reader, null, properties);
  }

  public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
    try {
      XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        reader.close();
      } catch (IOException e) {
        // Intentionally ignore. Prefer previous error.
      }
    }
  }

  public SqlSessionFactory build(InputStream inputStream) {
    return build(inputStream, null, null);
  }

  public SqlSessionFactory build(InputStream inputStream, String environment) {
    return build(inputStream, environment, null);
  }

  public SqlSessionFactory build(InputStream inputStream, Properties properties) {
    return build(inputStream, null, properties);
  }

  public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        inputStream.close();
      } catch (IOException e) {
        // Intentionally ignore. Prefer previous error.
      }
    }
  }

  public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }

}

 

应用场景一:多个参数查询拼接

需求: 根据各种参数查询订单,如根据类型查询订单统计,根据订单单号查询订单详情

 

思考:  可以用Builder方式,含括所有的参数,然后根据具体的参数进行拼接

 

订单查询参数类:OrderParam

public class OrderParam {


    private String startTime;

    private String endTime;

    private String orderType;

    private String orderSeries;

    private String areaCode;

 
    public String getStartTime() {

        return startTime;

    }


    public void setStartTime(String startTime) {

        this.startTime = startTime;

    }


    public String getEndTime() {

        return endTime;

    }


    public void setEndTime(String endTime) {

        this.endTime = endTime;

    }


    public String getOrderType() {

        return orderType;

    }


    public void setOrderType(String orderType) {

        this.orderType = orderType;

    }


    public String getOrderSeries() {

        return orderSeries;

    }


    public void setOrderSeries(String orderSeries) {

        this.orderSeries = orderSeries;

    }


    public String getAreaCode() {

        return areaCode;

    }


    public void setAreaCode(String areaCode) {

        this.areaCode = areaCode;

    }


    public OrderParam(BeanBuilder beanBuilder) {

        this.startTime = beanBuilder.startTime;

        this.endTime = beanBuilder.endTime;

        this.orderType = beanBuilder.orderType;

        this.orderSeries = beanBuilder.orderSeries;

        this.areaCode = beanBuilder.areaCode;

    }

    public static class BeanBuilder {

        private String startTime;

        private String endTime;

        private String orderType;

        private String orderSeries;

        private String areaCode;


        public BeanBuilder startTime(String startTime) {

            this.startTime = startTime;

            return this;

        }

        public BeanBuilder endTime(String endTime) {

            this.endTime = endTime;

            return this;

        }


        public BeanBuilder orderType(String orderType) {

            this.orderType = orderType;

            return this;

        }


        public BeanBuilder orderSeries(String orderSeries) {

            this.orderSeries = orderSeries;

            return this;

        }


        public BeanBuilder areaCode(String areaCode) {

            this.areaCode = areaCode;

            return this;

        }


        // 返回对应的主类

        public OrderParam builder() {

            return new OrderParam(this);

        }


    }


    @Override

    public String toString() {

        return "OrderParam{" +

                "startTime='" + startTime + '\'' +

                ", endTime='" + endTime + '\'' +

                ", orderType='" + orderType + '\'' +

                ", orderSeries='" + orderSeries + '\'' +

                ", areaCode='" + areaCode + '\'' +

                '}';

    }

}

 

订单查询参数测试类: OrderParamBuilderTest

 

import static org.junit.jupiter.api.Assertions.assertEquals;

import static org.junit.jupiter.api.Assertions.assertNotNull;



public class OrderParamBuilderTest {

    public static void main(String[] agrs) {

        OrderParam orderParam = new OrderParam.BeanBuilder().startTime("2021-01-01 00:00:00").endTime("2021-01-05 23:59:59").orderType("es").orderSeries("yan").areaCode("456451")

                .builder();

        assertNotNull(orderParam);

        assertNotNull(orderParam.toString());

        System.out.println(orderParam.toString());

        assertEquals("123", orderParam.getAreaCode());

    }

}

 

结果:

OrderParam{startTime='2021-01-01 00:00:00', endTime='2021-01-05 23:59:59', orderType='es', orderSeries='yan', areaCode='456451'}

Exception in thread "main" org.opentest4j.AssertionFailedError: expected: <123> but was: <456451>

    at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:52)

    at org.junit.jupiter.api.AssertEquals.failNotEqual(AssertEquals.java:177)

    at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:172)

    at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:163)

    at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:481)

请求参数拼接 OrderController

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;



@RequestMapping("/order")

public class OrderController {

    /**

     * 查询订单类型的统计

     * @param orderType 订单类型

     * @return

     */

    @GetMapping("/getOrderTypeStatics")

    public Object getOrderTypeStatics(@RequestParam(required = false) String orderType) {

        OrderParam orderParam = new OrderParam.BeanBuilder().orderType(orderType).builder();

        // 具体业务


        return "getOrderTypeStatics 查询回来的值";

    }

    /**

     *  查询订单详情

     * @param orderSeries 订单单号

     * @param areaCode 区域

     * @return

     */

    @GetMapping("/getOrderDetail")

    public Object getOrderDetail(@RequestParam String orderSeries, @RequestParam(required = false) String areaCode) {

        OrderParam orderParam = new OrderParam.BeanBuilder().orderSeries(orderSeries).areaCode(areaCode).builder();

        // 具体业务


        return "getOrderDetail查询回来的值";

    }


    /**

     *  查询订单列表信息

     * @param startTime  开始时间

     * @param endTime 结束时间

     * @param orderSeries 订单单号

     * @param orderType 订单类型

     * @param areaCode 区域

     * @return

     */

    @GetMapping("/getOrderInfo")

    public Object getOrderInfo(@RequestParam(required = false) String startTime, @RequestParam(required = false) String endTime,

                                  @RequestParam(required = false) String orderSeries, @RequestParam(required = false) String orderType,

                                  @RequestParam(required = false) String areaCode) {

        OrderParam orderParam = new OrderParam.BeanBuilder().startTime(startTime).endTime(endTime).orderSeries(orderSeries).orderType(orderType).areaCode(areaCode).builder();

        // 具体业务


        return "getOrderInfo 查询回来的值";

    }

}
 

 

总结:

应用场景之一: 多个查询参数的情况下,用于构建传递参数。

builder模式的不足:

(1)为了创建西对象,必须先创建它的构建器。增加了创建构建器的开销。当然大部分时候创建构建器的开销几乎微不足道。

(2)Builder模式比重叠构造器(不同参数组合的构造器)更加冗长,因此它只适合在很多参数的时候使用。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

天狼1222

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

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

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

打赏作者

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

抵扣说明:

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

余额充值