将构建器保留在单独的类中(流畅的界面) [英] Keeping builder in separate class (fluent interface)

查看:18
本文介绍了将构建器保留在单独的类中(流畅的界面)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

所以我知道有以下Builder"解决方案用于在调用方法时创建命名参数.虽然,这似乎只适用于作为构建器的内部静态类,还是我错了?我查看了一些关于构建器模式的教程,但对于我尝试做的事情来说,它们似乎非常复杂.有没有什么办法可以让 Foo 类和 Builder 类分开,同时还能像上面的代码一样享受命名参数的好处?

So I know there is the following "Builder" solution for creating named parameters when calling a method. Although, this only seems to work with inner static classes as the builder or am I wrong? I had a look at some tutorials for builder pattern but they seem really complex for what im trying to do. Is there any way to keep the Foo class and Builder class separate while having the benefit of named parameters like the code above?

在典型设置下:

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) 类中的所有属性.

Use composition. To make things easier and cleaner, do not replicate all attributes in source (Foo) and builder (Builder) class.

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

For example, have Foo class inside Builder instead of each of Foo attribute.

简单的代码片段:

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 是一个复杂的对象,具有以下使用组合的属性:

  1. FaceBookUser is a complex object with below attributes using composition:

String userName;
UserBasicInfo userInfo;
ContactInfo contactInfo;

  • FaceBookUserBuilder 是一个静态构建器类,包含并构建FaceBookUser.

  • FaceBookUserBuilder is a static builder class, which contains and builds FaceBookUser.

    userName 只是构建 FaceBookUser 的必备参数

    userName is only Mandatory parameter to build FaceBookUser

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

    FaceBookUserBuilder builds FaceBookUser by setting optional parameters : UserBasicInfo and ContactInfo

    这个例子说明了三个不同的 FaceBookUsers,它们具有不同的属性,由 Builder 构建.

    This example illustrates three different FaceBookUsers with different attributes, built from Builder.

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

  • 在这个例子中,使用组合而不是复制 Builder 类中 FaceBookUser 的所有属性.

    In this example, composition has been used instead of duplicating all attributes of FaceBookUser in Builder class.

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

    Group all related attributes into logical classes. Define all these classes in FaceBookUser. Instead of adding all these member variables again in Builder, contain FaceBookUser in Builder class.

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

    For simplicity, I have added two classes: UserBasicInfo and ContactInfo . Now explode this FaceBookUser class with other attributes like

    NewsFeed
    Messages
    Friends
    Albums
    Events
    Games
    Pages
    Ads
    

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

    If you duplicate all these attributes in both Builder and FaceBookUser, code will become difficult to manage. Instead, by using composition of FaceBookUser in FaceBookUserBuilder itself, you can simply construction process.

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

    Once you add above attributes, you will build FaceBookUser in step-by-step process as usual.

    它会是这样的:

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

    这篇关于将构建器保留在单独的类中(流畅的界面)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆