文章目录
一、如何理解建造者?
-
建造者模式,简单理解,以往我们通过new的方式来获取对象,现在,在建造者模式中,则是通过对目标类的建造者对象进行字段赋值,然后由建造者对象以这些字段为基础,给我们建造出我们想要的目标类
-
建造者模式将复杂对象的构建逻辑从对象本身抽离了出来,这样能够简化复杂的对象
- 参考StringBuilder的append方法,具体如何追加内容,就交给AbstractStringBuilder的append方法进行操作即可。从而实现将复杂对象的构建逻辑从对象本身中抽离了出来。
-
建造者模式(Builder)是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节
-
建造者的传统实现方式,可分为以下角色:
- Director,指挥者,负责把控创建TargetObject对象的流程(先后顺序)
- Builder,抽象建造者,抽离创建TargetObject对象的所需要的动作
- ConcreteBuilder,具体建造者,具体实现创建TargetObject对象的所需要的动作
- TargetObject,目标类
二、深入分析建造者
(一)为什么会有建造者模式
在软件开发中,复杂对象往往拥有复杂的成员字段,成员字段之间还可能存在着相互制约,比如有些字段的赋值必须按照某个顺序,一个字段没有赋值之前,另一个字段可能无法赋值等。
它主要解决复杂的对象创建,比如参数过长、校验过多等等。
如果当前对象比较重要,我们希望对象被创建之后就不能被修改,所以这时候set方法就会被屏蔽,如果利用构造函数,又会出现字段过多问题
与工厂模式相比,工厂模式要求我们对产品的内部细节不过多关注,我们知道,要想生成某个产品,我们需要事先在工厂的创建方法中,把如何生成这件产品的过程确定好了,这会导致在实际使用过程中,面对不同的场景,光靠工厂生产的对象是不足以满足我们需求的。
我们可以发现,在工厂模式下,我们无法做到对一个产品进行更加详细的描述,比如,这个苹果是大是小时,通过工厂模式都不能比较好地解决这个问题。
(二)优缺点分析
1、优点
-
易于拓展:想要建唱歌机器人只要单独将这个类像跳舞人那样建好,交给Director角色就可以了。无需修改原有代码。符合“开闭原则”
-
代码解耦,模块化,方便维护:产品本身与创建过程解耦,可以使用相同的创建过程得到不同的产品,而不同的产品由与之对应的Builder决定。
-
使用建造者模式的好处是不用担心忘了指定某个配置,保证了构建过程是稳定的
-
建造者模式用于创建过程稳定,但配置多变的对象
-
建造者模式从另外一个角度,是在解决抽象工厂模式的局限性,即不能纵向扩展
2、缺点
-
使用范围有限。
建造者模式创造出来的产品,其组成部分基本相同。比如跳舞机器人和唱歌机器人
如果产品之间的差异较大,则不适用这个模式。比如大象和猴子,不然需要为每个差异性的产品重新再走一遍上面的流程
(三)建造者模式 VS 工厂模式
-
建造者模式的好处,就是能够将对象的创建过程与对象本身隔离开来,就是说不直接与对象打交道来创建对象
-
建造者模式与工厂模式的不同
建造者模式,我们可以看到,在创建对象的时候,我们可以根据实际的需要去配置对象,比如要一大杯摩卡咖啡,小杯摩卡咖啡。
但是工厂模式,它生成的是一个粗略的对象,因为我们可以看到,在工厂模式中,我们已经提前把创建对象的方法编写好,包括其配置,要的时候,直接拿就可以了。
三、从JDK+MyBatis角度分析建造者模式
(一)StringBuilder 建造者模式的运用
StringBuilder顶层类Appendable是一个接口,接口中定义了抽象方法用来定义规范,AbstractStringBuilder类实现Appendable接口重写方法
- Appendable接口定义了多个append方法(抽象方法),即Appendable为抽象建造者。
- AbstractStringBuilder实现了Appendable接口方法,此时AbstractStringBuilder已经是具体建造者,但由于是抽象类所以不能实例化
- StringBuilder既充当指挥者角色,同时充当具体的建造者,建造方法的实现是由AbstractStringBuilder完成,StringBuilder继承了AbstractStringBuilder,通过调用父类方法实现具体建造
(二)MyBatis 建造者模式的运用
MyBatis 的 Environment 使用静态内部类Builder是建造者模式经典实现
-
这是建造者模式经典实现
-
Environment 没有提供 set 方法,因此外部调用者不能修改内部