Builder的定义就是:将一个复杂对象的构建于它的表示分离,使得同样的构建过程可以创建不同的表示。我想说构建我懂,表示?什么意思?我的理解是将对象的构建过程和构建出来的结果分离,在之前,你怎么写构造基本就决定了对象的样子,调用不同的构造语句即可得到不同的对象,而我们希望用几乎一样构造语句创建出不同的对象,只是通过传递不同的参数即可完成。分离构建与表示的关键在于,抽象出构建过程,将对象的构建固定成几个步骤,就像流水线,一个环节跟着一个环节,比如说饮料都是上瓶子,装水,盖上盖子,贴标签,但是对于可乐和雪碧他们的瓶子不一样,盖子不一样,内容不一样,标签也不一样,但都是这四步流程。这是一个内部的小封装处理。Builder的思路就很类似了。
对于一个产品Product,有a、b、c三个属性,Builder是Product的建造者,有点工厂的味道,在Builder中,我们把a、b、c的构建封装起来,但如果仅仅是这样,那每增加一个类,都得建一个对应的Builder,多态啊,当然要对Builder进行一次多态处理,创建一个AbstractBuilder,这样用一个AbstractBuilder指针就可以了。可是如果要在每次创建之后分别进行各种属性设置,还是比较繁琐。我们需要用一个东西将所有的属性设置函数封装起来完成,添加一个操作封装类,Director,这个类就是组装产品步骤的,就是设计流水线。对于客户端来说,只需要对Director调用操作就行了,哎,我是对着UML图来写的,你要是看晕了,建议在对着UML图再看一遍:
图来源于这儿。
图中显示,Product定义了一个类,其构造函数并没有干多少实际的事情,就只是建了一个空壳,而真正的流水线是在Builder中完成,对于Product所对应的Builder有所有的流水工序,而最终完成是靠一个Direct类,Direct类中有AbstractBuilder指针,这样就能随意调用了,那么最后Builder模式呈现的效果是,对每一种相同工序的Product都可以定义一个对应的Builder类,最后用Direct为接口,通过AbstractBuilder指针完成所有流水线加工。
对比Builder模式和Abstract Factory模式,前者是对相同构建工序的产品(比如可乐和雪碧)进行一个抽象封装,后者是将相同族群的产品(构建过程不要求,比如Windows和Linux)进行抽象。共同之处都是针对对象的创建下功夫,工厂是将创建搬到工厂中,用一个抽象工厂指针搞定,Builder是将创建搬到Builder中并且打散,汆成多步,用一个Direct统一调用。