前言

近日,看到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. 相对于父元素的fixed定位的实现

    问题描述 之前在项目中,遇到了一个场景,需要实现相对于父元素的fixed定位:在父元素内拖动滚动条时,"fixed"定位的元素不能滑动,在外层拖动滚动条时,父元素及父元素内的所有元 ...

  2. python3调用zabbix api

    前言 今天写了一个zabbix api,这里整理一下,过程中自己也学习了一些东西. 需求 我们需要查一个文件内容如下: cat /ops/flume_hosts node1 node2 需要把这个文件 ...

  3. noip第13课资料

  4. Hadoop 系列文章(一) Hadoop 的安装,以及 Standalone Operation 的启动模式测试

    以前都是玩 java,没搞过 hadoop,所以以此系列文章来记录下学习过程 安装的文件版本.操作系统说明 centos-6.5-x86_64 [bamboo@hadoop-senior opt]$ ...

  5. 推荐使用OpenLiveWriter在cnblogs上写的Blog

    这是我第一个使用OpenLiveWriter在cnblogs上写的Blog.不知道效果如何,但又很多功能我可以采用! 如表格功能:   Open Live Writer Write  on Web 优 ...

  6. RxSwift学习笔记9:amb/tabkeWhile/tabkeUntil/skipWhile/skipUntil

    //amb基本介绍 //当传入多个 Observables 到 amb 操作符时,它将取第一个发出元素或产生事件的 Observable,然后只发出它的元素. //并忽略掉其他的 Observable ...

  7. 如何将uniurlframe中html调用delphi的函数

    uniGUI总群中台中cmj朋友为我们总结了如下内容,对于利用delphi+uniGUI开发应用,可以说是精品,必须掌握. 一句话,如何在html与delphi间交互代码,是最好的答案. [Clien ...

  8. redis 实现发布订阅的功能

    redis 除了作为缓存的功能外还可以用作消息中间件的功能,这片博客主要是介绍一下 redis 整合spring 实现消息的发布和订阅功能: 1:redis依赖,依赖两个包,redis 包, spri ...

  9. css 设计规范

    外部 div 设置 margin 和 padding: 内部每个元素只设计跟自己相关的属性,这样方便复用:

  10. Rolling Hash about the Rsync

    今天看文献看到一个有趣的算法—Rolling Hash,这个算法可以更新在不同的machine上的两个“similar”的文件,也叫做rsync algorithm,rsync顾名思义:remote ...