设计模式-----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模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型和内容就可以构 ...
随机推荐
- Django的学习进阶(一)—— 外键的使用
一.描述 在利用django做网络开发的时候我们会遇到一个问题就是,我们建立了多张数据表,但是多张数据表中的内容是不一样的,但是之间有着联系比如: 我有两张表,一张是记录歌曲信息的内容,一张是对歌曲操 ...
- javascript 跨域 的几种方法
1.jsonp方法 转:https://blog.csdn.net/liusaint1992/article/details/50959571 主要实现功能: 1.参数拼装. 2.给每个回调函数唯 ...
- Aizu 0525 Osenbei 搜索 A
Aizu 0525 Osenbei https://vjudge.net/problem/Aizu-0525 题目: IOI製菓では,創業以来の伝統の製法で煎餅(せんべい)を焼いている.この伝統の製法 ...
- 1131 Subway Map DFS解法 BFS回溯!
In the big cities, the subway systems always look so complex to the visitors. To give you some sense ...
- Nextday 参数化单元测试(测试用例)设计
一.首先简单描述一下下载试题及配置试题的过程 配置环境:安装Eclipse.JDK(1.7).及考试插件 (net.mooctest....*.jar)等: 登录系统:运行Eclipse: [Mooc ...
- [CocoaPods]制作CocoaPod
创建自己的CocoaPod非常简单.如果你已经有一个单独的组件,那么你就是最重要的.本指南概述了整个过程,本节中的其他指南更适合更高级用户. 我们建议让CocoaPods在这里努力工作.Running ...
- python中的数字取整(ceil,floor,round)概念和用法
python中的数学运算函数(ceil,floor,round)的主要任务是截掉小数以后的位数.总体来说 就是取整用的.只是三者之间有微妙的区别: floor() :把数字变小 ceil() : ...
- javascript 异步解析
js 异步解析 一 .js单线程分析 我们都知道js的一大特点是单线程,也就是同一时间点,只能处理一件事,一句js代码.那为什么js要设计成单线程而不是多线程呢?这主要和js的用途有关,js作为浏览器 ...
- django xlwt实现资产导出功能
做个记录 views import xlwt class ExAssetView(LoginRequiredMixin,View): def get(self,request): row = 1 st ...
- 机器视觉编程作业02(00)EM算法
任务:对图像进行边缘检测 思路: )将图像的灰度数值进行0-255的维度统计: )EM算法分析出几个核心显示区块的灰度: )使用通用的边界检测算法(具体哪一种待定). 编辑于2017.12.24 15 ...