构建复杂对象

作者: MrCoding | 来源:发表于2016-02-01 18:11 被阅读993次

本文定位于理解和总结<Effective Java>的所讲内容,而不是翻译,因此不当之处,还请广大网友指出。

复杂对象在这里指的是有三个以上(不包括三个)的属性的对象。当一个类具有很多属性时,使用构造器或者静态工厂的方式创建新对象时不可避免的需要对很多属性进行赋值,可维护性与可读性都很低。

通常使用重叠构造器(telescoping constructor)或者JavaBean模式来构建新对象(两种模式具体代码实例可参见<Effective Java>),可以提高代码可维护性和可读性,然而这两种方法并不完美。

重叠构造器模式

重叠构造器模式是指类有一系列的构造器,构造器的入参从仅包含必选参数依次递增到包含所有参数,且必选参数构造器通过逐级调用后续构造器来实现。

实际上,重叠构造器模式并没有解决任何问题,当可变参数增多时,客户端代码依然难写又难读,并且扩展性极差,每增加一个属性都要修改很多级的构造器。

JavaBean模式

JavaBean模式是指先通过无参的构造器来创建对象,然后通过setter填充属性的方法来构建新对象。

相对于重叠构造器模式来说,JavaBean模式可读性,可维护性,可扩展性都很高,但是JavaBean模式本身存在严重的缺陷。

  • 对象在构建过程中存在不一致性的可能
    由于对象的构建分多次调用才能完成,在构建完成之前,使用对象可能会引起运行时错误,编译期无法察觉。

  • 对象是可变的
    由于使用setter来构建对象,导致对象本身就失去了成为不可变对象的可能。

  • 需要依赖程序员来保证线程安全
    不一致性导致需要程序员额外的工作来保证线程安全。

构建者模式

除了以上两种方式以外,还可以使用构建者模式来创建对象,构建者模式通过吸收必选参数和链式配置可选参数来完成对象的构建。一般情况下,构建者模式可实现为构建对象的内部类。如下:

// Builder Pattern
public class NutritionFacts {
  private final int servingSize;
  private final int servings;
  private final int calories;
  private final int fat;
  private final int sodium;
  private final int carbohydrate;
  public static class Builder {
    // Required parameters
    private final int servingSize;
    private final int servings;
    // Optional
    private int calories = 0;
    private int fat = 0;
    private int carbohydrate = 0;
    private int sodium = 0;

    public Builder(int servingSize, int servings) {
      this.servingSize = servingSize;
      this.servings = servings;
    }
    public Builder calories(int val){ 
      calories = val;
      return this;
    }
    public Builder fat(int val){
      fat = val;
      return this;
    }
    public Builder carbohydrate(int val){
      carbohydrate = val; 
      return this;
    }
    public Builder sodium(int val){
      sodium = val;
      return this;
    }
    public NutritionFacts build() {
      return new NutritionFacts(this);
    }
  }
  private NutritionFacts(Builder builder) {
    servingSize = builder.servingSize;
    servings = builder.servings;
    calories = builder.calories;
    fat = builder.fat;
    sodium = builder.sodium;
    carbohydrate = builder.carbohydrate;
  }
}

在创建对象之前,需要先创建该对象构建者的对象,并提供必选参数,随后链式配置可选参数,调用构建方法来完成对象的构建,如下:

NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();

构建者模式融合了以上两种方式的优点,同时也避免了缺点,既保证了可读性和可维护性又提高了线程安全。

因此当遇到有三个以上属性的复杂对象构建,尤其是有一些属性是可选属性时,不妨考虑使用构建者模式。

相关文章

  • 构建复杂对象

    本文定位于理解和总结的所讲内容,而不是翻译,因此不当之处,还请广大网友指出。 复杂...

  • 建造者模式

    建造者模式 定义: 封装一个复杂对象的构建过程,可以按照流程来构建对象。 优点:它可以将复杂对象的构建与表示相分离...

  • 建造者模式

    概念:使用多个复杂的对象构造成一个复杂的对象。 目的:将复杂的构建与表现相分离,使同样的构建可以构建不同的表示。-...

  • 创建--建造者

    定义:将一个复杂对象的构建和表示分离,使同一个构建过程可以创建不同的表示分步构建一个复杂对象,复杂对象的各个部分经常变化

  • Builder模式

    通过Builder来构建产品对象, 而Director封装了构建复杂产品对象对象的过程, 不对外隐藏构建细节. 实...

  • 只一篇就够了·设计模式(4) - 建造者模式

    建造者模式(Builder Pattern)简化了构建复杂对象的过程,除了简化复杂的对象的构建过程,最核心的思想是...

  • 01- 构建者模式(Builder Pattern)

    设计模式 构建者模式 概述: 当创建复杂对象的时候,可以使用构建者模式,把创建复杂对象的过程分离出来,并且保持对象...

  • 程序员内功心法【设计模式】之建造者模式

    基本定义 建造者模式将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。 建造者模式构建复杂对象...

  • 5、创建型设计模式-建造者模式

    建造者模式(Builder Pattern) 使用多个简单的对象一步一步构建成一个复杂的对象,将一个复杂对象的构建...

  • 2019-02-21——设计模式 建造者模式

    特点 封装一个复杂对象的构建过程,并可以按步骤构造。将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建...

网友评论

    本文标题:构建复杂对象

    本文链接:https://www.haomeiwen.com/subject/qbuskttx.html