教你用设计模式之建造者模式

前言

设计模式的各种解释和例子在网上可谓是多如牛毛,LZ又不厌其烦的写一个关于设计模式的系列,自然会有不一样的侧重点。本系列的侧重点在:

  1. 怎么使用(确定用的是这个模式,而不是用成了其他模式)
  2. 为什么要使用(有什么好处)
  3. 什么情况下使用

一、怎么使用(特点)

类图

设计到的角色(类)

  1. 产品(Product)角色
      由一系列部件组成,一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量。在本类图中,产品类是一个具体的类,而非抽象类。实际编程中,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成。

  2. 抽象建造者(Builder)角色
      给出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此接口独立于应用程序的商业逻辑。模式中直接创建产品对象的是具体建造者 (ConcreteBuilder)角色。具体建造者类必须实现这个接口所要求的两种方法:一种是建造方法(buildPart),另一种是返还结构方法(getResult)。一般来说,产品所包含的零件数目与建造方法的数目相符。换言之,有多少零件,就有多少相应的建造方法。
      引入抽象建造者的目的,是为了将建造的具体过程交与它的子类来实现。这样更容易扩展。一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回产品。

  3. 具体建造者(ConcreteBuilder)角色
      实现抽象类的所有未实现的方法,具体来说一般是两项任务:组建产品;返回组建好的产品。

  4. 导演者(Director)角色
      负责调用适当的建造者来组建产品,导演类一般不与产品类发生依赖关系,与导演类直接交互的是建造者类。一般来说,导演类被用来封装程序中易变、及其复杂的部分。导演者角色并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者角色。

导演者角色是与客户端打交道的角色。导演者将客户端创建产品的请求划分为对各个零件的建造请求,再将这些请求委派给具体建造者角色。具体建造者角色是做具体建造工作的,但是却不为客户端所知。

一般来说,每有一个产品类,就有一个相应的具体建造者类。这些产品应当有一样数目的零件,而每有一个零件就相应地在所有的建造者角色里有一个建造方法。

建造模式分成两个很重要的部分:
  1. 一个部分是Builder接口,这里是定义了如何构建各个部件,也就是知道每个部件功能如何实现,以及如何装配这些部件到产品中去;
  2. 另外一个部分是Director,Director是知道如何组合来构建产品,也就是说Director负责整体的构建算法,而且通常是分步骤地来执行。
  不管如何变化,建造模式都存在这么两个部分,一个部分是部件构造和产品装配,另一个部分是整体构建的算法。认识这点是很重要的,因为在建造模式中,强调的是固定整体构建的算法,而灵活扩展和切换部件的具体构造和产品装配的方式。
  再直白点说,建造模式的重心在于分离构建算法和具体的构造实现,从而使得构建算法可以重用。具体的构造实现可以很方便地扩展和切换,从而可以灵活地组合来构造出不同的产品对象。

二、为什么要使用

首先,建造者模式的封装性很好。使用建造者模式可以有效的封装变化,在使用建造者模式的场景中,一般产品类和建造者类是比较稳定的,因此,将主要的业务逻辑封装在导演类中对整体而言可以取得比较好的稳定性。

其次,建造者模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险。

建造模式利用一个导演者对象和具体建造者对象一个个地建造出所有的零件,从而建造出完整的产品对象。建造者模式将产品的结构和产品的零件的建造过程对客户端隐藏起来,把对建造过程进行指挥的责任和具体建造者零件的责任分割开来,达到责任划分和封装的目的。

三、什么情况下使用

  1. 创建复杂对象的算法独立于组成对象的部件
  2. 同一个创建过程需要有不同的内部表象的产品对象

建造者模式与工厂模式的区别
   我们可以看到,建造者模式与工厂模式是极为相似的,总体上,建造者模式仅仅只比工厂模式多了一个“导演类”的角色。在建造者模式的类图中,假如把这个导演类看做是最终调用的客户端,那么图中剩余的部分就可以看作是一个简单的工厂模式了。
  与工厂模式相比,建造者模式一般用来创建更为复杂的对象,因为对象的创建过程更为复杂,因此将对象的创建过程独立出来组成一个新的类——导演类。也就是说,工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类向客户端提供最终的产品;而建造者模式中,建造者类一般只提供产品类中各个组件的建造,而将具体建造过程交付给导演类。由导演类负责将各个组件按照特定的规则组建为产品,然后将组建好的产品交付给客户端。

四、总结

设计模式总共就23种,其实很少,了解起来也并不是很难,大家肯定也看过很多讲解的文章或者书籍,但是,当真正使用起来的时候,往往又会遇到不知道什么场景用该用哪个模式等等困惑,究其原因还是没有掌握每个模式的特点和运用的场景。所以,我们再学习设计模式的过程中,千万不能囫囵吞枣,需要仔细探究每个模式的本质,并学会抽象归类总结,要有一个属于自己的思维过程,这样,设计模式才是属于我们的模式。
  设计模式本质也是一个个算法,这些算法解决了一个问题,什么问题呢?--它为人们提供了一个简单高效的程序设计方法来满足设计模式六大原则,知道了这点,在去理解设计模式六大原则后来理解设计模式,或许有更好的效果

五、参考文章

  1. 23种设计模式(4):建造者模式
  2. 《JAVA与模式》之建造模式
  3. Builder Pattern
  4. Java Design Pattern: Builder

推荐阅读更多精彩内容