前言

近日,看到Myabtis中组件中SqlSessionFactory由SqlSessionFactoryBuilder().build()生成时,且采用Builder模式,遂记录学习之。

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

1、什么是Builder模式?

  (1)对于复杂的对象,如果只是用构造方法创建的话,构造方法中会存在很多的逻辑,那么我们可以一步步有秩序构建它,从而降低复杂度;

  (2)对于复杂的对象,使用者不必知道其内部是如何实现的清下,逐步构造需要的实例对象;

2、什么情况下使用Builder模式?

  (1)将一个复杂对象的构建与它的表示分离,即相同的构造过程可以有不同表示;

  (2)当有多个构造器且需要传入不同的参数表示不同的产品时(即可以弥补工厂模式等无法选择多参数的缺点)

  (3)传入参数情况比较灵活且复杂的情况,或者说一开始不需要明确参数的情况。

  (4)框架中很多Configuration配置都会用到Builder模式。

3、具体使用Builder例子

(1)以前经常通过不同构造器传入不同的参数构造不同复杂的对象,比如我们现在需要一个User的不同情况对象

  • 只有id和name
  • 有id、name、age
  • 有id、name、age、address
public class User {
private int id;
private String name;
private int age;
private String address; //不同的构造器传入不同的参数,创造不同的复杂的产品
public User(int id, String name) {
this.id = id;
this.name = name;
}
public User(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public User(int id, String name, int age, String address) {
this.id = id;
this.name = name;
this.age= age;
this.address = address;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getAddress() {
return address;
} public void setAddress(String address) {
this.address = address;
}
}

测试类这样编写:

public class Main {
public static void main(String[] args) {
//情况1:id、姓名
User user = new User(1, "Zhangsan");
//情况2:id、姓名、年龄
User user2 = new User(2,"Lisi",22);
//情况3:id、姓名、年龄、地址
User user3 = new User(3,"Wangwu",23,"Beijing");
//情况4:id与年龄不清楚,很容易混淆,必须得查看源码或者文档才能知道哪个参数位置id/年龄
User user4 = new User(24,"Wangwu",24,"Beijing");
}
}

OK,这样是没有问题的,但是会有以下弊端:

  • 就好比情况4。当传入的参数很多并且没有说明文档的情况下,之后阅读完源码后才能更好地使用。那么就有可能对源码进行修改,这样就违背了在应用中一个好的设计模块的原则,即设计模式中的开闭原则(Open-Closed Principle, OCP,对修改封闭)
  • 每种情况都得编写一个的构造器,没有一点的灵活度。再比如这里address属性是可选的,可以不传入,那么灵活度同样很低!

(2)接下来就使用Builder模式创建,注意:Builder主要采用Java静态内部类

/**
* 利用Builer模式灵活面对复杂对象的创建
* @author Lijian
*
*/
public class User2 {
private int id;
private String name;
private int age;
private String address; private User2(Builder builder) {
this.id = builder.id;
this.name = builder.name;
this.age = builder.age;
this.address = builder.address;
}
static class Builder{
private int id;
private String name;
private int age;
private String address;
//灵活选择参数
public Builder setId(int id) {
this.id = id;
return this;
}
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setAddress(String address) {
this.address = address;
return this;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
//最后build返回User2对象
public User2 build() {
return new User2(this);
}
}
}

测试类:

public class Main {
public static void main(String[] args) {
//通过build创建了User2对象,之后通过setXXX方法可灵活初始化属性,最后build返回对象
User2 user = new User2.Builder().setId(1).setName("Lijian").setAge(22).build();
//情况1:id、姓名
User2 user2 = new User2.Builder().setId(2).setName("Zhangsan").build();
//情况2:id、姓名、年轻、地址
User2 user3 = new User2.Builder().setId(2).setName("Lisi").build();
//情况3:id与age很明显能区分
User2 user4 = new User2.Builder().setId(23).setAge(23).build();
}
}

通过setXXX()方法灵活选择参数,最后build()方法“闭合”返回对象。很适用于复杂对象的创建,此处让我想起Java8新特性中的Stream API(https://blog.csdn.net/mynewclass/article/details/80393308)的一个特点:懒加载。是的,有点“懒加载”的味道,不需要立马指定属性,也不会立马生效,之后最后的操作build()才会生效!

设计模式-----Builder模式的更多相关文章

  1. java设计模式--Builder模式

    一.Builder模式 二.使用例子 三.Spring中的Builder模式 Builder模式,构建者.构造者模式,在<图解设计模式>中归为 生成实例 一栏,该模式用于组装具有复杂结构的 ...

  2. java的设计模式 - Builder模式

    Builder 模式的目的? 构造对象的方式过于复杂,不如将之抽离出来.比如,构造器参数过多 这样说也有点抽象,举个例子吧. 举个例子 比如 非常热门的消息队列RabbitMQ 的 AMQP.Basi ...

  3. android 开发设计模式---Builder模式

    我们通过一个例子来引出Builder模式.假设有一个Person类,我们通过该Person类来构建一大批人,这个Person类里有很多属性,最常见的比如name,age,weight,height等等 ...

  4. 设计模式-Builder模式(创建型模式)

    //以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //Product.h #pragma once class Product { public: Product(); ~ ...

  5. 设计模式Builder(建造者)模式

    1.出现原因 在软件系统中,有时候会面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成:由于需求的变化,这个复杂的对象的各个部分可能面临着剧烈的变化,但是把他们组合在一起的算法 ...

  6. Android开发中常见的设计模式(二)——Builder模式

    了解了单例模式,接下来介绍另一个常见的模式--Builder模式. 那么什么是Builder模式呢.通过搜索,会发现大部分网上的定义都是 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建 ...

  7. 设计模式之构建者(Builder)模式

    在五大设计原则的基础上经过GOF(四人组)的总结,得出了23种经典设计模式,其中分为三大类:创建型(5种).结构型(7种).行为型(11种).今天对创建型中的构建者(Builder)模式的思想进行了一 ...

  8. Java设计模式-建造者(Builder)模式

    目录 由来 使用 1. 定义抽象 Builder 2. 定义具体 Builder类 3. 定义具体 Director类 4. 测试 定义 文字定义 结构图 优点 举例 @ 最近在看Mybatis的源码 ...

  9. Java设计模式(3)建造者模式(Builder模式)

    Builder模式定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. Builder模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型和内容就可以构 ...

随机推荐

  1. 【转】《深入理解C# 3.x的新特性》博文系列汇总

    [转]<深入理解C# 3.x的新特性>博文系列汇总 较之C# 2.0, C# 3.x引入了一系列新的特性,为我们编程带来很大的便利,通过有效地利用这些新特性,我们可以编写出更加简洁.优雅的 ...

  2. android开发环境配置以及测试所遇到的的问题

    今天我没有继续进行,整理了一线之前犯下的错误.在一开始的android的环境配置的时候,按照网上的教程,我还是走了许多弯道,其中遇到了不少的问题,但是现在都一一解决了. 配置时安装东西少 在配置的时候 ...

  3. SWPU-ACM集训队周赛之组队赛(3-11) C题题解

    点这里去看题 模拟,注意细节 #include<stdio.h> #include<string.h> int main() { ]; //q[]储存正负信息 scanf(&q ...

  4. openresty 安装

    1.安装环境.版本说明: 操作系统: Centos 6.5 X86_64 openresty 版本: openresty-1.13.6.1.tar.gz 2.安装 openresty(nginx) 需 ...

  5. Gitlab配置、备份、升级、迁移

    0.Gitlab安装 1.安装和配置必要的依赖关系 在CentOS7,下面的命令将在系统防火墙打开HTTP和SSH访问. yum install curl openssh-server postfix ...

  6. [Python] networkx入门 转

    networkx是python的一个第三方包,可以方便地调用各种图算法的计算. 通过调用python画图包matplotlib能实现图的可视化. 1.安装 正好整理一下python第三方包的安装方法. ...

  7. RabbitMQ 常用操作

    RabbitMQ简介 1.首先安装erlang rpm -Uvh https://www.rabbitmq.com/releases/erlang/erlang-19.0.4-1.el7.centos ...

  8. DOM扩展:DOM API的进一步增强[总结篇-上]

    DOM1级主要定义了文档的底层结构,并提供了基本的查询操作的API,总体而言这些API已经比较完善,我们可以通过这些API完成大部分的DOM操作.然而,为了扩展DOM API的功能,同时进一步提高DO ...

  9. Django(序列化、SweetAlert插件)

    day72 参考:https://www.cnblogs.com/liwenzhou/p/8718861.html#autoid-6-1-2 前端序列化 后端序列化 day73中 补充一个SweetA ...

  10. Java 11 快要来了,编译 & 运行一个命令搞定!

    Java 11 马上要来了,原定于 9 月发布,还有不到 3 个月了,敬请期待更多新功能被加入到 11 当中,本文本讲的是 JEP 330 这个新特性. 化繁为简,一个命令编译运行源代码 看下面的代码 ...