为什么要在构建器模式下使用#NewBuilder()函数?是必不可少的吗?

发布于 2025-02-13 12:51:54 字数 784 浏览 0 评论 0原文

我以前就一直在使用构建器模式,但是这些天来,我的一所大学都以我从未想过的问题向我传达,并且是关于#NewBuilder()在构建器模式中的功能。

我在几个论坛,教程甚至API中都看到过,当使用构建器模式时,通常会使用类似的结构:

Car car1 = new CarBuilder().newBuilder().twoDoors().fourWheels().build();

通常,在#NewBuilder()函数中,有一个类似的代码:

public static CarBuilder newBuilder(){
  return new CarBuilder();
}

问题是,为什么需要在构建器类中需要一个#newbuilder()函数?拥有它是一个好习惯,还是只有在施加过载时才需要?我的意思是,仅在我需要超载具有不同参数的2或3个不同#NewBuilder()函数的#NewBuilder()函数的情况下。

如果我只有一个#newbuilder()函数在构建器类中怎么办?我应该实现它吗?还是可以避免它并做类似的事情:

Car car1 = new CarBuilder().twoDoors().fourWheels().build();

我的同事的问题是:如果我实现#newbuilder()函数,如果我只有一个#newbuilder( )在我的构建器课程中功能吗?

您如何看待这个?我是否应该将其删除,或者是合理地拥有#NewBuilder()函数,尽管我只有一个实现而没有超载?

谢谢!

I am using the Builder Pattern since time ago, but these days one of my collegues reach me with a question to which I never thought about, and is about the #newBuilder() function in the Builder Pattern.

I've seen in several forums, tutorials, and even APIs, that when using the Builder Pattern, a structure like this is usually used:

Car car1 = new CarBuilder().newBuilder().twoDoors().fourWheels().build();

Usually, inside of the #newBuilder() function, there is a code like this:

public static CarBuilder newBuilder(){
  return new CarBuilder();
}

The question is, why should be needed a #newBuilder() function in the Builder class? Is it a good practice to have it, or is needed only when overloading is applied? I mean, just in the cases where I need to overload the #newBuilder() having 2 or 3 different #newBuilder() functions with different parameters.

What if I will have only one #newBuilder() function in the Builder class? Should I implement it, or can I avoid it and do something like:

Car car1 = new CarBuilder().twoDoors().fourWheels().build();

The question of my colleague was: If I implement the #newBuilder() function, am I falling in redundancy with the first example if I will only have one #newBuilder() function in my Builder class?

What you think about this? Should I remove it or it is justified to have the #newBuilder() function despite of I have only one implementation of it without overloading?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我为君王 2025-02-20 12:51:54

请注意,这是:

  car car1 = new carbuilder()。newbuilder()。twodoors()。twodoors()。four four fortheels()。build()。build();
 

绝对是多余的,但不是因为存在newbuilder()方法。问题是您的代码本质上是这样的:

CarBuilder builder1 = new CarBuilder();
CarBuilder builder2 = builder1.newBuilder();
Car car1 = builder2.twoDoors().fourWheels().build();

换句话说,您正在创建两个实例 Carbuilder。另外,您在实例参考上调用static方法,该方法皱眉了。使用当前的设置,您的代码应为:

Car car1 = new CarBuilder().twoDoors().fourWheels().build();

或:

Car car1 = CarBuilder.newBuilder().twoDoors().fourWheels().build();

您选择的哪种样式取决于您。但是,如果您选择使用第二种方法(静态出厂方法newbuilder()),则通常制作构建器的构造函数private,或者至少是软件包 - 私有关系,因此,新Carbuilder()不能由外部代码使用。

因此,我会说“否”,只要您正确使用newbuilder()本身并不是多余的。这只是创建构建器实例而无需直接调用构造函数的替代方法。注意使用静态出厂方法方法可能有助于可读性,因为您可以将其命名为更具描述性的方法。但是,除非您有大量具有不同语义的工厂方法,否则您可能不会看到这种优势。


要考虑的另一件事是将newbuilder()静态方法放置在哪里。如果CarbuilderCAR非常耦合,那么许多开发人员将将静态方法放入CAR类中,而不是Carbuilder 类(如果不只是后者筑巢)。

例如:

package sample;

public final class Car {

  public static CarBuilder newBuilder() {
    return new CarBuilder();
  }

  private final int numberOfDoors;
  private final int numberOfWheels;

  Car(CarBuilder builder) {
    this.numberOfDoors = builder.numberOfDoors;
    this.numberOfWheels = builder.numberOfWheels;
  }

  // getters and setters omitted for brevity
}
package sample;

public final class CarBuilder {

  private int numberOfDoors; // should initialize to sensible default
  private int numberOfWheels; // should initialize to sensible default

  CarBuilder() {}

  public CarBuilder twoDoors() {
    numberOfDoors = 2;
    return this;
  }

  public CarBuilder fourWheels() {
    numberOfWheels = 4;
    return this;
  }

  public Car build() {
    return new Car(this);
  }
}

然后可以像这样使用:

Car car1 = Car.newBuilder().twoDoors().fourWheels().build();

Note that this:

Car car1 = new CarBuilder().newBuilder().twoDoors().fourWheels().build();

Is definitely redundant, but not because the newBuilder() method exists. The problem is your code is essentially this:

CarBuilder builder1 = new CarBuilder();
CarBuilder builder2 = builder1.newBuilder();
Car car1 = builder2.twoDoors().fourWheels().build();

In other words, you're creating two instances of CarBuilder. Also, you're calling a static method on an instance reference, which is frowned upon. With your current setup, your code should be either:

Car car1 = new CarBuilder().twoDoors().fourWheels().build();

OR:

Car car1 = CarBuilder.newBuilder().twoDoors().fourWheels().build();

Which style you choose is up to you. However, if you choose to use the second approach (the static factory method newBuilder()), then typically the builder's constructor is made private, or at least package-private, so that new CarBuilder() cannot be used by external code.

So, I would say "no", having newBuilder() is not redundant in and of itself, as long as you use it correctly. It's simply an alternative way of creating a builder instance without calling the constructor directly. Note using the static factory method approach may aid in readability, because you can name the method something more descriptive. You may not see that advantage unless you have a significant number of different factory methods with different semantics, however.


Another thing to consider is where to place the newBuilder() static method. If CarBuilder and Car are extremely coupled, then many developers will put the static method in the Car class instead of the CarBuilder class (if not just nest the latter in the former).

For example:

package sample;

public final class Car {

  public static CarBuilder newBuilder() {
    return new CarBuilder();
  }

  private final int numberOfDoors;
  private final int numberOfWheels;

  Car(CarBuilder builder) {
    this.numberOfDoors = builder.numberOfDoors;
    this.numberOfWheels = builder.numberOfWheels;
  }

  // getters and setters omitted for brevity
}
package sample;

public final class CarBuilder {

  private int numberOfDoors; // should initialize to sensible default
  private int numberOfWheels; // should initialize to sensible default

  CarBuilder() {}

  public CarBuilder twoDoors() {
    numberOfDoors = 2;
    return this;
  }

  public CarBuilder fourWheels() {
    numberOfWheels = 4;
    return this;
  }

  public Car build() {
    return new Car(this);
  }
}

Which could then be used like so:

Car car1 = Car.newBuilder().twoDoors().fourWheels().build();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文