通俗易懂系列 | 设计模式(八):建造者模式

介绍

今天咱们将研究java中的Builder模式。Builder 设计模式是一种创造性的设计模式,如工厂模式和抽象工厂模式。
当Object包含许多属性时,引入了Builder模式来解决Factory和Abstract Factory设计模式的一些问题。
当Object包含许多属性时,Factory和Abstract Factory设计模式存在三个主要问题。java

  1. 从客户端程序传递到Factory类的参数太多,可能容易出错,由于大多数状况下,参数的类型是相同的,而从客户端来讲,很难维护参数的顺序。
  2. 一些参数多是可选的,但在Factory模式中,咱们被迫发送全部须要发送为NULL的参数和可选参数。
  3. 若是对象很重而且它的建立很复杂,那么全部这些复杂性都将成为Factory类的一部分,使人困惑。

咱们能够经过提供具备所需参数的构造函数而后使用不一样的setter方法来设置可选参数来解决大量参数的问题。这种方法的问题是,除非明确设置全部属性,不然Object状态将不一致。git

Builder模式经过提供逐步构建对象的方法并提供实际返回最终Object的方法,解决了大量可选参数和不一致状态的问题。github

意图

将复杂对象的构造与其表示分开,以便相同的构造过程能够建立不一样的表示。算法

定义

现实世界的例子设计模式

想象一下角色扮演游戏的角色生成器。最简单的选择是让计算机为您建立角色。可是若是你想选择职业,性别,头发颜色等角色细节,那么角色生成将成为一个按部就班的过程,在全部选择准备就绪时完成。app

简单来讲函数

容许您建立不一样风格的对象,同时避免构造函数被污染。当有几种不一样的构造函数时颇有用。或者在建立对象时涉及不少步骤。ui

维基百科说this

构建器模式是对象建立软件设计模式,其目的是找到伸缩构造器反模式的解决方案。翻译

话虽如此,让我补充说一下伸缩构造器反模式是什么。某时某刻,咱们都会看到以下构造函数:

public Hero(Profession profession, String name, HairType hairType, HairColor hairColor, Armor armor, Weapon weapon) {
}

正如您所看到的,构造函数参数的数量很快就会失控,而且可能很难理解参数的排列。此外,若是您但愿未来添加更多选项,此参数列表可能会继续增加。这就被称为"the telescoping constructor anti-pattern"(可伸缩构造器的反模式)。

理智的替代方案是使用Builder模式。

实例

让咱们看看如何在java中实现构建器设计模式。

  1. 首先,您须要建立一个静态嵌套类,而后将全部参数从外部类复制到Builder类。咱们应该遵循命名约定,若是类名是Computer那么构建器类应该命名为ComputerBuilder。
  2. Java Builder类应该有一个公共构造函数,其中包含全部必需的属性做为参数。
  3. Java Builder类应具备设置可选参数的方法,而且应在设置可选属性后返回相同的Builder对象。
  4. 最后一步是build()在构建器类中提供一个方法,该方法将返回客户端程序所需的Object。为此,咱们须要在Class中使用Builder类做为参数的私有构造函数。

下面是示例构建器模式示例代码,首先,咱们有咱们想要创造的英雄

public final class Hero {
  private final Profession profession;
  private final String name;
  private final HairType hairType;
  private final HairColor hairColor;
  private final Armor armor;
  private final Weapon weapon;

  private Hero(Builder builder) {
    this.profession = builder.profession;
    this.name = builder.name;
    this.hairColor = builder.hairColor;
    this.hairType = builder.hairType;
    this.weapon = builder.weapon;
    this.armor = builder.armor;
  }
}

而后咱们有了建设者

public static class HeroBuilder {
    private final Profession profession;
    private final String name;
    private HairType hairType;
    private HairColor hairColor;
    private Armor armor;
    private Weapon weapon;

    public Builder(Profession profession, String name) {
      if (profession == null || name == null) {
        throw new IllegalArgumentException("profession and name can not be null");
      }
      this.profession = profession;
      this.name = name;
    }

    public Builder withHairType(HairType hairType) {
      this.hairType = hairType;
      return this;
    }

    public Builder withHairColor(HairColor hairColor) {
      this.hairColor = hairColor;
      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);
    }
  }

请注意,Hero类只有getter方法,没有公共构造函数。所以,获取Hero对象的惟一方法是经过HeroBuilder类。

而后它能够用做以下,显示如何使用Builder类来获取对象:

Hero mage = new Hero.HeroBuilder(Profession.MAGE, "Riobard").withHairColor(HairColor.BLACK).withWeapon(Weapon.DAGGER).build();

使用场景

使用Builder模式时

  • 用于建立复杂对象的算法应该独立于构成对象的部分以及它们如何组装
  • 构造过程必须容许对构造的对象进行不一样的表示

JDK中的Builder设计模式示例

Java类中的一些构建器模式示例是;

  • java.lang.StringBuilder#append()(未同步)
  • java.lang.StringBuffer#append()(synchronized)

总结

优势: 一、建造者独立,易扩展。 二、便于控制细节风险。
缺点: 一、产品必须有共同点,范围有限制。 二、如内部变化复杂,会有不少的建造类。
注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。

这就是java中的构建器设计模式的所有内容。
翻译于:builder-design-pattern-in-java
参考:java-design-patterns

相关文章
相关标签/搜索