编程语言
首页 > 编程语言> > java – 在单独的类中保持构建器(流畅的界面)

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

作者:互联网

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

说明:

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

String userName;
UserBasicInfo userInfo;
ContactInfo contactInfo;

> FaceBookUserBuilder是一个静态构建器类,它包含并构建FaceBookUser.
> userName只是构建FaceBookUser的必需参数
> FaceBookUserBuilder通过设置可选参数来构建FaceBookUser:UserBasicInfo和ContactInfo
>此示例说明了使用Builder构建的具有不同属性的三种不同FaceBookUser.

> fbUser1仅作为FaceBookUser构建,仅具有userName属性
> fbUser2使用userName和UserBasicInfo构建为FaceBookUser
> fbUser3使用userName,UserBasicInfo和ContactInfo构建为FaceBookUser

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

编辑:

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

为简单起见,我添加了两个类:UserBasicInfo和ContactInfo.现在使用其他属性来爆炸这个FaceBookUser类

NewsFeed
Messages
Friends
Albums
Events
Games
Pages
Ads

等等

如果在Builder和FaceBookUser中复制所有这些属性,代码将变得难以管理.相反,通过在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();

标签:fluent,builder-pattern,java,design-patterns
来源: https://codeday.me/bug/20190926/1820064.html