在 Builder 模式中添加静态“builder()”方法有什么好处?

问题描述 投票:0回答:1

我想知道我对 Builder 模式的实现是否错误。
假设我们有一个

User
类,我们想要一个
Builder
,我的实现是:

public class User
{
    private final String name;
    private final int age;
        
    private User(Builder builder)
    {
        this.name = builder.name;
        this.age = builder.age;
    }  
       
    public static class Builder
    {
        //blah blah
            
        public User build()
        {
            return new User(this);
        }
    }
}

但时不时地,我看到有人添加这个方法:

public static Builder builder()
{
    return new Builder();
}

除了实现稍微更具可读性的语法之外,似乎没有其他原因:

//Before
User user = new User.Builder()
    .named("Tester")
    .build();

//After
User user = User.builder()
    .named("Tester")
    .build();

这是唯一的优势吗?我错过了什么吗?

java implementation builder
1个回答
0
投票

关于您最初的问题:

我对Builder模式的实现是否错误

恕我直言,您的代码使用了不正确的依赖项。

您的

User
类必须了解
Builder
的内部结构

private User(Builder builder)
{
    this.name = builder.name;
    this.age = builder.age;
}

应该反过来:

Builder
应该了解
User
的施工要求。
User
类甚至不应该知道有任何构建者可以帮助构建。

所以,我将其重构为

public class User
{
    private final String name;
    private final int age;
        
    private User(String name, int age)
    {
        this.name = name;
        this.age = age;
    }  
       
    public static class Builder
    {
        //blah blah
            
        public User build()
        {
            return new User(name, age);
        }
    }
}

关于静态

builder()
方法:

您始终将类和方法引入为 Java 语言的特定于域的扩展,从而允许您的用户使用新词汇编写应用程序代码。

问题始终是:“你的新词汇是否让班级的来电者变得更容易?”

那么,您希望如何用您的应用程序特定语言创建

User
?一些可能性:

  • new User("Tester", 42);
    如果参数超过两个,这可能会变得相当不清楚,缺乏灵活性。
  • User.withNameAndAge("Tester", 42);
    这迫使您提供许多类似的静态方法。
  • User.builder().named("Tester").aged(42).build();
    这听起来好像您想为构建者而不是用户命名。
  • new User.Builder().named("Tester").aged(42).build();
    这听起来好像您想为构建者而不是用户命名。
  • User.named("Tester").aged(42).build();
    读起来很不错,但实现起来有点复杂
  • new User().named("Tester").aged(42);
    这很容易阅读,但存在初始化不完整的风险。

确定你认为最好的(关于可读性、灵活性、稳健性……),然后实施它。对于某些创作风格,您需要一个

Builder
类,对于其他风格,它可能在幕后有帮助,而对于其他风格,则没有必要。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.