gpt4 book ai didi

java - 将构建器保持在单独的类中(流畅的界面)

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:22:37 27 4
gpt4 key购买 nike

Foo foo = Foo.builder()
.setColor(red)
.setName("Fred")
.setSize(42)
.build();

所以我知道有以下“Builder”解决方案,用于在调用方法时创建命名参数。虽然,这似乎只适用于作为构建器的内部静态类,还是我错了?我看过一些关于构建器模式的教程,但它们对于我想要做的事情来说似乎真的很复杂。有什么方法可以让 Foo 类和 Builder 类分开,同时享受上面代码中命名参数的好处?

下面是一个典型的设置:

public class Foo {
public static class Builder {
public Foo build() {
return new Foo(this);
}

public Builder setSize(int size) {
this.size = size;
return this;
}

public Builder setColor(Color color) {
this.color = color;
return this;
}

public Builder setName(String name) {
this.name = name;
return this;
}

// you can set defaults for these here
private int size;
private Color color;
private String name;
}

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

private Foo(Builder builder) {
size = builder.size;
color = builder.color;
name = builder.name;
}

private final int size;
private final Color color;
private final String name;
}

最佳答案

使用组合。为了使事情变得更简单和更清晰,不要复制源 (Foo) 和构建器 (Builder) 类中的所有属性。

例如,Builder 中有 Foo 类,而不是每个 Foo 属性。

简单的代码片段:

import java.util.*;

class UserBasicInfo{
String nickName;
String birthDate;
String gender;

public UserBasicInfo(String name,String date,String gender){
this.nickName = name;
this.birthDate = date;
this.gender = gender;
}

public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("Name:DOB:Gender:").append(nickName).append(":").append(birthDate).append(":").
append(gender);
return sb.toString();
}
}

class ContactInfo{
String eMail;
String mobileHome;
String mobileWork;

public ContactInfo(String mail, String homeNo, String mobileOff){
this.eMail = mail;
this.mobileHome = homeNo;
this.mobileWork = mobileOff;
}
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("email:mobile(H):mobile(W):").append(eMail).append(":").append(mobileHome).append(":").append(mobileWork);
return sb.toString();
}
}
class FaceBookUser {
String userName;
UserBasicInfo userInfo;
ContactInfo contactInfo;

public FaceBookUser(String uName){
this.userName = uName;
}
public void setUserBasicInfo(UserBasicInfo info){
this.userInfo = info;
}
public void setContactInfo(ContactInfo info){
this.contactInfo = info;
}
public String getUserName(){
return userName;
}
public UserBasicInfo getUserBasicInfo(){
return userInfo;
}
public ContactInfo getContactInfo(){
return contactInfo;
}

public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("|User|").append(userName).append("|UserInfo|").append(userInfo).append("|ContactInfo|").append(contactInfo);
return sb.toString();
}

static class FaceBookUserBuilder{
FaceBookUser user;
public FaceBookUserBuilder(String userName){
this.user = new FaceBookUser(userName);
}
public FaceBookUserBuilder setUserBasicInfo(UserBasicInfo info){
user.setUserBasicInfo(info);
return this;
}
public FaceBookUserBuilder setContactInfo(ContactInfo info){
user.setContactInfo(info);
return this;
}
public FaceBookUser build(){
return user;
}
}
}
public class BuilderPattern{
public static void main(String args[]){
FaceBookUser fbUser1 = new FaceBookUser.FaceBookUserBuilder("Ravindra").build(); // Mandatory parameters
UserBasicInfo info = new UserBasicInfo("sunrise","25-May-1975","M");

// Build User name + Optional Basic Info
FaceBookUser fbUser2 = new FaceBookUser.FaceBookUserBuilder("Ravindra").
setUserBasicInfo(info).build();

// Build User name + Optional Basic Info + Optional Contact Info
ContactInfo cInfo = new ContactInfo("xxx@xyz.com","1111111111","2222222222");
FaceBookUser fbUser3 = new FaceBookUser.FaceBookUserBuilder("Ravindra").
setUserBasicInfo(info).
setContactInfo(cInfo).build();

System.out.println("Facebook user 1:"+fbUser1);
System.out.println("Facebook user 2:"+fbUser2);
System.out.println("Facebook user 3:"+fbUser3);
}
}

输出:

Facebook user 1:|User|Ravindra|UserInfo|null|ContactInfo|null
Facebook user 2:|User|Ravindra|UserInfo|Name:DOB:Gender:sunrise:25-May-1975:M|ContactInfo|null
Facebook user 3:|User|Ravindra|UserInfo|Name:DOB:Gender:sunrise:25-May-1975:M|ContactInfo|email:mobile(H):mobile(W):xxx@xyz.com:1111111111:2222222222

解释:

  1. FaceBookUser 是一个复杂的对象,使用组合具有以下属性:

    String userName;
    UserBasicInfo userInfo;
    ContactInfo contactInfo;
  2. FaceBookUserBuilder 是一个静态构建器类,它包含并构建 FaceBookUser

  3. userName只是构建FaceBookUser的必选参数

  4. FaceBookUserBuilder 通过设置可选参数构建 FaceBookUser:UserBasicInfoContactInfo

  5. 此示例展示了三个不同的 FaceBookUsers,它们具有不同的属性,是从 Builder 构建的。

    1. fbUser1 被构建为仅具有 userName 属性的 FaceBookUser
    2. fbUser2 被构建为具有 userName 和 UserBasicInfo 的 FaceBookUser
    3. fbUser3 被构建为 FaceBookUser,具有 userName、UserBasicInfo 和 ContactInfo

在此示例中,使用了组合,而不是复制 Builder 类中 FaceBookUser 的所有属性。

编辑:

将所有相关属性分组到逻辑类中。在 FaceBookUser 中定义所有这些类。不是在 Builder 中再次添加所有这些成员变量,而是在 Builder 类中包含 FaceBookUser

为简单起见,我添加了两个类:UserBasicInfo 和 ContactInfo。现在用其他属性展开这个 FaceBookUser 类,比如

NewsFeed
Messages
Friends
Albums
Events
Games
Pages
Ads

等等

如果在 BuilderFaceBookUser 中复制所有这些属性,代码将变得难以管理。相反,通过在 FaceBookUserBuilder 本身中使用 FaceBookUser 的组合,您可以简化构造过程。

添加上述属性后,您将像往常一样逐步构建 FaceBookUser

它会是这样的:

FaceBookUser fbUser3 = new FaceBookUser.FaceBookUserBuilder("Ravindra").
setUserBasicInfo(info).
setNewsFeed(newsFeed).
setMessages(messages).
setFriends(friends).
setAlbums(albums).
setEvents(events).
setGames(games).
setAds(ads).build();

关于java - 将构建器保持在单独的类中(流畅的界面),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39708728/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com