Java通俗易懂系列设计模式之建造者模式

作者:JaJian 时间:2022-11-01 23:27:24 

介绍

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

  1. 从客户端程序传递到Factory类的参数太多,可能容易出错,因为大多数情况下,参数的类型是相同的,而从客户端来说,很难维护参数的顺序。

  2. 一些参数可能是可选的,但在Factory模式中,我们被迫发送所有需要发送为NULL的参数和可选参数。

  3. 如果对象很重并且它的创建很复杂,那么所有这些复杂性都将成为Factory类的一部分,令人困惑。

我们可以通过提供具有所需参数的构造函数然后使用不同的setter方法来设置可选参数来解决大量参数的问题。这种方法的问题是,除非明确设置所有属性,否则Object状态将不一致。

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

意图

将复杂对象的构造与其表示分开,以便相同的构造过程可以创建不同的表示。

定义

现实世界的例子:

想象一下角色扮演游戏的角色生成器。最简单的选择是让计算机为您创建角色。但是如果你想选择职业,性别,头发颜色等角色细节,那么角色生成将成为一个循序渐进的过程,在所有选择准备就绪时完成。

简单来说:

允许您创建不同风格的对象,同时避免构造函数被污染。当有几种不同的构造函数时很有用。或者在创建对象时涉及很多步骤。

* 说:

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

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


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

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

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

实例

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

  • 首先,您需要创建一个静态嵌套类,然后将所有参数从外部类复制到Builder类。我们应该遵循命名约定,如果类名是Computer那么构建器类应该命名为ComputerBuilder。

  • Java Builder类应该有一个公共构造函数,其中包含所有必需的属性作为参数。

  • Java Builder类应具有设置可选参数的方法,并且应在设置可选属性后返回相同的Builder对象。

  • 最后一步是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)

来源:https://www.cnblogs.com/jajian/p/9749138.html

标签:Java,设计模式,建造者模式
0
投稿

猜你喜欢

  • java的三种随机数生成方式

    2022-03-06 13:43:57
  • Android中Activity之间跳转和参数传递的实例

    2023-01-31 21:40:32
  • hadoop中实现java网络爬虫(示例讲解)

    2021-12-22 01:35:20
  • Java中常用缓存Cache机制的实现

    2023-05-27 23:32:22
  • Java 定时任务技术趋势详情

    2021-10-29 14:48:13
  • Swing常用组件之多行文本区JTextArea

    2023-11-08 14:16:49
  • C#委托delegate实例解析

    2021-07-28 08:58:26
  • Java System类两个常用方法代码实例

    2023-02-01 13:52:15
  • Java事件机制要素及实例详解

    2022-11-27 07:10:53
  • Java异常处理操作 Throwable、Exception、Error

    2022-02-19 20:56:13
  • C#中foreach循环对比for循环的优势和劣势

    2021-12-29 23:50:59
  • Java调用Oracle存储过程详解

    2022-09-09 03:19:45
  • Android一行代码实现圆形头像

    2022-02-23 02:00:25
  • Android通知栏前台服务的实现

    2022-10-13 22:57:46
  • Java服务限流算法的6种实现

    2022-04-03 04:52:51
  • Jackson库中objectMapper的用法

    2023-10-25 13:20:40
  • 实例分析java开启线程的方法

    2022-06-24 19:54:00
  • Java调用windows系统的CMD命令并启动新程序

    2021-11-27 17:09:13
  • android实现歌词自动滚动效果

    2022-03-16 17:09:10
  • RocketMQ生产者一个应用不能发送多个NameServer消息解决

    2022-05-18 15:56:11
  • asp之家 软件编程 m.aspxhome.com