前言

近日,看到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. STL基础4:deque

    #include <iostream> #include <queue> #include <string> using namespace std; #defin ...

  2. 配置微信jssdk自定义分享

    前段时间做这个功能的时候遇到这个问题,之前的话是微信自动抓取界面第一张图,现在微信更新api,必须自行配置,接入jssdk,才能实现该功能. 详细可以查看微信的jssdk文档 微信官方开发者文档    ...

  3. unique(未完成)

    const unique = arr => { const sortedArr = arr.sort((a, b) => a > b); const first = sortedAr ...

  4. lucene的suggest(搜索提示功能的实现)

    1.首先引入依赖 <!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-suggest --> <!-- ...

  5. 《mysql必知必会》学习_第20章_20180809_欢

    第20章:更新和删除数据 P140 update customers set_emails='elmer@fudd.com' where cust_id=10005; 更新多个列,用逗号隔开.注意被指 ...

  6. 某公司的C#面试题

    1. 请简述值类型与引用类型的区别 答: 可参考http://www.cnblogs.com/JimmyZhang/archive/2008/01/31/1059383.html 2.C#中所有引用类 ...

  7. iOS 不能加载电子签名

    问题: 1:使用WKWebView在iOS12.0以上的系统中,可以显示PDF中的电子图章,签名.在iOS12.0以下的系统中不能显示电子签名,图章. 2:  解决方案,使用PDF.js加载. pdf ...

  8. stm32驱动12832液晶屏程序(ST7565R控制器)

    LCD12832.c文件: #include"stm32f10x_lib.h" #include "OCM12232.h" void Lcd12232delay ...

  9. LeetCode算法题(长期更新)

    1.给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数组中同样 ...

  10. [W3bSafe]Metasploit溢出渗透内网主机辅助脚本

    文章来源i春秋 脚本用Shell编写  有的内网特别脆弱  本脚本主要就是 测试的话方便一点   输入内网网关就能调用Metasploit全部模块测试整个内网 运行截图<ignore_js_op ...