前言

“我要打十个”,其实是我要打十个野怪!

这十个野怪呢,它们有不同的技能、装备和武器,长得也不一样。这里野怪是一个蛮复杂的对象,由各个不同的部分组成(技能、装备、武器等),不同的野怪的它们各部分之间的构成方式就不同。因此,要创建这种复杂对象,就需要使用建造者模式。

什么是建造者模式

首先建造者模式Gof 23种设计模式之一。也叫Builder模式。

是将一个复杂对象的构建和其表示相分离,使得同样的构建过程可以创建不同的表示。

我们来品一品这句话,首先是复杂对象,这个复杂对象中可能包含了多个不同的其他对象。其次是这个复杂对象的创建一定是用到了这些其他对象,通过一定的算法组合能才创建出这个对象。最后就是它能通过builder创建出一些特性不同但相似的对象。

好了,借用Linus 名言:

Talk is cheap. Show me the code!!!

代码实现

开始创建我们的野怪类,就叫做Hero吧,它的组成部分有技能类Skill,装备类Armor 和武器类Weapon 。

创建Skill、Armor和Weapon类

public class Skill {private String skillName;public Skill(String skillName) {this.skillName = skillName;}@Overridepublic String toString() {return "Skill{" +"skillName='" + skillName + '\'' +'}';}
}public class Armor {private String armorName;public Armor(String armorName) {this.armorName = armorName;}@Overridepublic String toString() {return "Armor{" +"armorName='" + armorName + '\'' +'}';}
}public class Weapon {private String weaponName;public Weapon(String weaponName) {this.weaponName = weaponName;}@Overridepublic String toString() {return "Weapon{" +"weaponName='" + weaponName + '\'' +'}';}
}

创建Hero类,在该类中,我们使用静态内部类的方式构建了Builder类,就是我们使用Builder类帮助我们创建对象。

忘了啥是内部类的,可以移驾下面这篇复习下。

Java内部类超详细总结(含代码示例)

public class Hero {private final String name;private final Skill skill;private final Armor armor;private final Weapon weapon;private Hero(Builder builder){this.name = builder.name;this.skill = builder.skill;this.armor = builder.armor;this.weapon = builder.weapon;}@Overridepublic String toString() {return "Hero{" +"name='" + name + '\'' +", skill=" + skill +", armor=" + armor +", weapon=" + weapon +'}';}public static class Builder{private final String name;private Skill skill;private Armor armor;private Weapon weapon;public Builder(String name){this.name = name;}public Builder withSkill(Skill skill){this.skill = skill;return this;}public Builder withArmor(Armor armor){this.armor = armor;return this;}public Builder withWeapon(Weapon weapon){this.weapon = weapon;return this;}public Hero build(){return new Hero(this);}}
}

好了,我们的builder模式的核心代码已经晚了,其实关键的就是Builder类,我们创建复杂对象就是通过Builder类封装了创建的细节,同时,Builder提供了一些公共方法,可以定制这些复杂对象的创建过程。

新建个测试类AppMain,测试一把。

public class AppMain {public static void main(String[] args) {Hero hero = new Hero.Builder("纳什男爵").withSkill(new Skill("飞龙在天")).withArmor(new Armor("亢龙铠甲")).withWeapon(new Weapon("唾沫星子")).build();System.out.println(hero);}
}

结果如下:

Hero{name='纳什男爵', skill=Skill{skillName='飞龙在天'}, armor=Armor{armorName='亢龙铠甲'}, weapon=Weapon{weaponName='唾沫星子'}}

当然了,这里也可以创建个“四鸟”,“河蟹”之类的。总之,你要打十个,么有问题啊,我们给你builder十个就好了,而且是不重样的。

Builder模式在源码中的应用

StringBuilder

其实我们熟知的StringBuilder就是builder模式的典型实现。我们平时使用基本都是这样:

        StringBuilder sb = new StringBuilder();sb.append(123).append('a').append(1.23).append(true).append("hhhh");

看着就很平常,soeasy的感觉,其实可以看到它能添加不同的数据类型进去,对应建造者模式中的各个部分,通过append方法的不同组合构建出了不同的StringBuilder对象。

看下源码:

    ......@Overridepublic StringBuilder append(boolean b) {super.append(b);return this;}@Overridepublic StringBuilder append(char c) {super.append(c);return this;}......

上面列举了两个重载方法,可以看到其实是调用了父类的重载方法,父类是AbstractStringBuilder

 // 这里只列举这一个父类的方法public AbstractStringBuilder append(boolean b) {if (b) {ensureCapacityInternal(count + 4);value[count++] = 't';value[count++] = 'r';value[count++] = 'u';value[count++] = 'e';} else {ensureCapacityInternal(count + 5);value[count++] = 'f';value[count++] = 'a';value[count++] = 'l';value[count++] = 's';value[count++] = 'e';}return this;}

Mybatis中的builder模式

Mybatis中的SqlSessionFactoryBuilder、XMLMapperBuilder、XMLStatementBuilder等都使用了builder模式。

这里简单看下SqlSessionFactoryBuilder

所有的build重载方法都在构建SqlSessionFactory 对象。只是可以根据需要调用不同的方法,传入不同的参数,就可以构建出特性不同的SqlSessionFactory 。

看下其中一个build方法的源码

    ......public SqlSessionFactory build(Reader reader, String environment, Properties properties) {SqlSessionFactory var5;try {XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);var5 = this.build(parser.parse());} catch (Exception var14) {throw ExceptionFactory.wrapException("Error building SqlSession.", var14);} finally {ErrorContext.instance().reset();try {reader.close();} catch (IOException var13) {}}return var5;}......

而且可以看到,这个方法中又使用了一个XMLConfigBuilder 。

Builder模式的使用场景

下面再总结一下builder模式的使用场景吧。

  • 创建复杂对象的算法应该独立于组成对象的部件及其组装方式。
  • 构造对象的过程允许所构造的对象的不同表示。

设计模式往期回顾

Java面试必备:手写单例模式

工厂模式超详解(代码示例)

设计模式之原型模式

设计模式之代理模式

设计模式之委派模式,大名鼎鼎的Spring都在用

公众号:二营长的笔记
免费领资料:公众号内回复“二营长”

我要打十个!详解建造者模式(builder pattern)相关推荐

  1. Net设计模式实例之建造者模式(Builder Pattern)(2)

    四.案例分析(Example) 1.场景 假设房子只有房顶和墙(Roof And Walls)<?XML:NAMESPACE PREFIX = O /> Jane和 Joe两个客户需要从建 ...

  2. Python 设计模式之建造者模式 Builder Pattern

    #引入建造者模式 肯德基的菜单上有 薯条, 鸡腿,鸡翅,鸡米花,可乐,橙汁,火腿汉堡,至尊虾汉堡,牛肉汉堡 , 鸡肉卷等这些单品,也有很多套餐. 比如 套餐1:鸡翅,至尊虾汉堡,可乐,薯条 套餐2:鸡 ...

  3. 大厦设计师 -- 建造者模式 (Builder Pattern) 介绍 使用案例场景分析 优缺点 及代码演示

    一句话概括: 使用多个简单对象一步一步构建成复杂对象,将复杂对象的构建与表示相分离. 补充介绍: 建造者模式(Builder Pattern)中有一个 Builder 类,这个类会一步一步构造最终的对 ...

  4. 设计模式(创建型)之建造者模式(Builder Pattern)

    PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbob ...

  5. UE4 C++设计模式:建造者模式(Builder Pattern)

    目录 描述 套路 使用场景 优缺点 UE4实践 具体复杂产品-门派角色 抽象建造者-角色构造器 具体建造者-纯阳角色构造器 具体建造者-七秀角色构造器 创建指挥者(Director)-角色创建指挥器 ...

  6. 详解Decorator模式和vistor模式

    详解Decorator模式和vistor模式 这两个模式是我在软件构造课程学习期间最不理解的两种模式,也是趁着考试前几天的复习,重新梳理了一下 Decorator装饰器模式 顾名思义,装饰器模式就是给 ...

  7. 嵌入式基础01【转载】详解大端模式和小端模式

    ---------------- 版权声明:本文为CSDN博主「ce123」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明. 原文链接:https://blog. ...

  8. 详解PPP模式下的产业投资基金运作【基金管理】

    详解PPP模式下的产业投资基金运作[基金管理] 点击标题下「搏实资本」可快速关注 搏实资本 研究型的投资机构,实操型的专家团队 ﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌ 一.产业投资基金概述 1.产业投资基 ...

  9. 详解大端模式和小端模式

    详解大端模式和小端模式 嵌入式开发交流群280352802,欢迎加入! 一.大端模式和小端模式的起源 关于大端小端名词的由来,有一个有趣的故事,来自于Jonathan Swift的<格利佛游记& ...

最新文章

  1. python线下培训-天津python培训,0基础学python线上还是线下好?
  2. 如何自学python数据分析-『』python数据分析该怎么入门呢?
  3. java between_Java8 Period.between方法坑及注意事项
  4. 如何忽略证书继续访问_前5个最容易被忽视的可访问性问题
  5. JS-封装js让一个div或者img的移动
  6. 阿里:千亿交易背后的0故障发布
  7. PHP+MySQL 手工注入语句大全 推荐
  8. linux man命令汉化 操作
  9. 【每天一个 Linux 命令】tree命令
  10. html5新增graph,Qunee for HTML5 - 中文 : Graph组件介绍
  11. 笔记本插入耳机依然外放,但开机前插上耳机可以使用耳机 (解决了我多年的问题)
  12. android6.0连接WIFI后显示“已连接,但无法访问互联网”实际可以上网
  13. Windows 10 支持AAC编码的方法
  14. java poi生成word 并插入 表格
  15. Android调用QQ加群代码
  16. CCF201809-4 再卖菜
  17. 对服务器整体性能画像,青云科技发布新一代企业级云服务器e3 绘制云基础设施标准画像...
  18. React入门小册(三)组件
  19. VI编辑器_终端编辑器(命令整理)
  20. 基因差异表达分析——基于RSEM对比,DESeq2操作实例

热门文章

  1. inotify+rsync详细说明和sersync
  2. win7计算机电源设置在哪里设置,Win7高级电源管理在哪?设置高级电源管理的方法...
  3. hook监控限制_iOS逆向之hook控制中心开关
  4. 5个能挣钱的自媒体平台
  5. springboot钱包支付系统
  6. LeetCode 刷题系列 -- 1110. 删点成林
  7. 【阅读笔记】时间序列之TPA-LSTM(含Pytorch代码实现)
  8. AutoCAD发展历程回顾
  9. 论文笔记:Hierarchical Deep Reinforcement Learning:Integrating Temporal Abstraction and Intrinsic
  10. Excel转换PDF:Speedpdf在线转换工具一键转换