设计模式-----Builder模式
前言
近日,看到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模式的更多相关文章
- java设计模式--Builder模式
一.Builder模式 二.使用例子 三.Spring中的Builder模式 Builder模式,构建者.构造者模式,在<图解设计模式>中归为 生成实例 一栏,该模式用于组装具有复杂结构的 ...
- java的设计模式 - Builder模式
Builder 模式的目的? 构造对象的方式过于复杂,不如将之抽离出来.比如,构造器参数过多 这样说也有点抽象,举个例子吧. 举个例子 比如 非常热门的消息队列RabbitMQ 的 AMQP.Basi ...
- android 开发设计模式---Builder模式
我们通过一个例子来引出Builder模式.假设有一个Person类,我们通过该Person类来构建一大批人,这个Person类里有很多属性,最常见的比如name,age,weight,height等等 ...
- 设计模式-Builder模式(创建型模式)
//以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //Product.h #pragma once class Product { public: Product(); ~ ...
- 设计模式Builder(建造者)模式
1.出现原因 在软件系统中,有时候会面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成:由于需求的变化,这个复杂的对象的各个部分可能面临着剧烈的变化,但是把他们组合在一起的算法 ...
- Android开发中常见的设计模式(二)——Builder模式
了解了单例模式,接下来介绍另一个常见的模式--Builder模式. 那么什么是Builder模式呢.通过搜索,会发现大部分网上的定义都是 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建 ...
- 设计模式之构建者(Builder)模式
在五大设计原则的基础上经过GOF(四人组)的总结,得出了23种经典设计模式,其中分为三大类:创建型(5种).结构型(7种).行为型(11种).今天对创建型中的构建者(Builder)模式的思想进行了一 ...
- Java设计模式-建造者(Builder)模式
目录 由来 使用 1. 定义抽象 Builder 2. 定义具体 Builder类 3. 定义具体 Director类 4. 测试 定义 文字定义 结构图 优点 举例 @ 最近在看Mybatis的源码 ...
- Java设计模式(3)建造者模式(Builder模式)
Builder模式定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. Builder模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型和内容就可以构 ...
随机推荐
- 【NIFI】 Apache NiFI 之 ExecuteScript处理(二)
本例介绍NiFI ExecuteScript处理器的使用,使用的脚本引擎ECMScript 接上一篇[NIFI] Apache NiFI 之 ExecuteScript处理(一) ExecuteScr ...
- python repr()和str()
两者功能差不多,都是把对象转为字符串表示形式,但是也有区别,repr()之后再eval()可以转为原型,但str()只能保证大多数,不能100% 其中主要的 差别在与 字符串对象本身,比如 a = ' ...
- 在Windows上安装Arduino的步骤
在64位Windows 10机器上测试 Windows Installer从arduino.cc下载并安装最新的Arduino IDE 从git-scm.com下载并安装Git 开始Git GUI并运 ...
- Build.gradle的详细配置说明
转自:http://blog.csdn.net/u012246458/article/details/51722624 apply plugin: 'com.android.application'/ ...
- RabbitMQ基本理论
本节内容 一 RabbitMQ介绍 二 RabbitMQ安装配置 三 RabbitMQ的Python实现-pika 1. 生产者消费者 2. 工作队列 3. 持久化和公平分发 4. 发布与订阅 ...
- iOS编码规范(简版)
1. 总体指导原则 [规则1-1]首先是为人编写程序,其次才是计算机. 说明:这是软件开发的基本要点,软件的生命周期贯穿产品的开发.测试.生产.用户使用.版本升级和后期维护等长期过程,只有易读.易维护 ...
- [.net core学习] .net core中的Rijndael取代方法
The difference (in .NET) between Rijndael and AES is that Rijndael allows the block size to change, ...
- 【洛谷4770】 [NOI2018]你的名字(SAM,线段树合并)
传送门 洛谷 Solution 做过的比较玄学的后缀自动机. 果然就像\(Tham\)所讲,后缀自动机这种东西考场考了不可能做的出来的... 考虑如果\(l=1,r=|S|\)的怎么做? 直接建后缀自 ...
- poj2699
神题目=神题解+神读入 题意:n个人比赛, 两两比,共n*(n-1), 赢得1分, n<=10(这给了我们枚举的暗示),如果一个人打败了所有比自己分数高的人, 或者他本身就是分数最高的, 那么他 ...
- 使用 JSON-lib 出现异常 java.lang.reflect.InvocationTargetException
我是在使用json时引起的这个异常,上面是使用json-lib用到的几个jar包,原因是在commons-lang3-3.1.jar这个jar上,commons-lang3和commons-lang会 ...