수색…


비고

같은 구조 프로세스가 다른 표현을 만들 수 있도록 복잡한 객체의 구성을 표현과 분리합니다.

  • 논리를 표현과 분리하십시오.
  • 논리를 재사용하여 다른 데이터 세트를 처리하십시오.

작성자 패턴 / C # / 유창한 인터프리터

public class Email
{
    public string To { get; set; }
    public string From { get; set; }
    public string Subject { get; set; }
    public string Body { get; set; }
}

public class EmailBuilder
{
    private readonly Email _email;

    public EmailBuilder()
    {
        _email = new Email();
    }

    public EmailBuilder To(string address)
    {
        _email.To = address;
        return this;
    }

    public EmailBuilder From(string address)
    {
        _email.From = address;
        return this;
    }

    public EmailBuilder Subject(string title)
    {
        _email.Subject = title;
        return this;
    }

    public EmailBuilder Body(string content)
    {
        _email.Body = content;
        return this;
    }

    public Email Build()
    {
        return _email;
    }
}

사용 예 :

var emailBuilder = new EmailBuilder();
var email = emailBuilder
    .To("[email protected]")
    .From("[email protected]")
    .Subject("Email subject")
    .Body("Email content")
    .Build();

작성자 패턴 / Java 구현

Builder 패턴을 사용하면 많은 선택적 변수가있는 클래스의 인스턴스를 읽기 쉬운 방식으로 작성할 수 있습니다.

다음 코드를 살펴보십시오.

public class Computer {

    public GraphicsCard graphicsCard;
    public Monitor[] monitors;
    public Processor processor;
    public Memory[] ram;
    //more class variables here...

    Computer(GraphicsCard g, Monitor[] m, Processer p, Memory ram) {
        //code omitted for brevity...
    }

    //class methods omitted...

}

모든 매개 변수가 필요한 경우 이는 모두 훌륭하고 좋은 것입니다. 더 많은 변수가 있거나 그 중 일부가 선택 적이라면? 유지 보수가 어렵고 개발자가 이해할 수 없기 때문에 필수 및 선택적 매개 변수의 가능한 조합마다 많은 수의 생성자를 생성하고 싶지는 않습니다. 많은 사람들이 사용자가 null로 입력해야 할 수도있는 매개 변수의 긴 목록을 갖고 싶지 않을 수도 있습니다.

Builder 패턴은 원하는 선택적 변수 만 인스턴스화하는 데 사용되는 Builder라는 내부 클래스를 작성합니다. 이것은 변수 타입을 매개 변수로 취하는 각 선택적 변수에 대한 메소드를 통해 수행되며 메소드가 서로 연결될 수 있도록 Builder 오브젝트를 리턴합니다. 필요한 모든 변수는 생략 할 수 없도록 Builder 생성자에 저장됩니다.

Builder에는 객체를 build() 할 때 메소드 호출 체인의 끝에서 호출되어야하는 객체를 반환하는 build() 라는 메서드가 포함되어 있습니다.

앞의 예제에 이어이 코드는 Computer 클래스에 대해 Builder 패턴을 사용합니다.

public class Computer {

    private GraphicsCard graphicsCard;
    private Monitor[] monitors;
    private Processor processor;
    private Memory[] ram;
    //more class variables here...

    private Computer(Builder builder) {
        this.graphicsCard = builder.graphicsCard;
        this.monitors = builder.monitors;
        this.processor = builder.processor;
        this.ram = builder.ram;
    }

    public GraphicsCard getGraphicsCard() {
        return this.graphicsCard;
    }

    public Monitor[] getMonitors() {
        return this.monitors;
    }

    public Processor getProcessor() {
        return this.processor;
    }

    public Memory[] getRam() {
        return this.ram;
    }

    public static class Builder {
        private GraphicsCard graphicsCard;
        private Monitor[] monitors;
        private Processor processor;
        private Memory[] ram;

        public Builder(Processor p){
            this.processor = p;
        }

        public Builder graphicsCard(GraphicsCard g) {
            this.graphicsCard = g;
            return this;
        }

        public Builder monitors(Monitor[] mg) {
            this.monitors = mg;
            return this;
        }

        public Builder ram(Memory[] ram) {
            this.ram = ram;
            return this;
        }

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

이 클래스를 사용하는 방법의 예 :

public class ComputerExample {

    public static void main(String[] args) {
        Computer headlessComputer = new Computer.Builder(new Processor("Intel-i3"))
                .graphicsCard(new GraphicsCard("GTX-960"))
                .build();

        Computer gamingPC = new Computer.Builder(new Processor("Intel-i7-quadcode"))
                .graphicsCard(new GraphicsCard("DX11"))
                .monitors(new Monitor[] = {new Monitor("acer-s7"), new Monitor("acer-s7")})
                .ram(new Memory[] = {new Memory("2GB"), new Memory("2GB"), new Memory("2GB"), new Memory("2GB")})
                .build();
    }

}

이 예제는 빌더 패턴을 사용하여 클래스 생성 과정에서 많은 노력을 기울일 수있는 방법을 보여줍니다. 컴퓨터 개체는 호출자가 원하는 구성을 기반으로 쉽게 읽을 수있는 방식으로 구현할 수 있습니다.

컴포지션이있는 Java의 작성자 패턴

의지:

동일한 표식이 다른 표현을 만들 수 있도록 복잡한 표식의 구성을 표현과 분리하십시오.

빌더 패턴은 필수 속성과 오브젝트를 구성하는 많은 선택적 속성이 거의없는 경우에 유용합니다. 서로 다른 필수 속성과 선택적 속성을 가진 객체를 만들려면 객체를 생성하기위한 복잡한 생성자를 제공해야합니다. 빌더 패턴은 복잡한 객체를 생성하기위한 간단한 단계별 프로세스를 제공합니다.

실제 사용 사례 :

FaceBook의 다른 사용자는 사용자 이름과 같은 필수 속성과 UserBasicInfo 및 ContactInfo와 같은 선택적 속성으로 구성된 서로 다른 속성을 가지고 있습니다. 일부 사용자는 기본 정보 만 제공합니다. 일부 사용자는 연락처 정보를 포함한 자세한 정보를 제공합니다. Builder 패턴이 없으면 모든 필수 및 선택적 매개 변수를 생성자에게 제공해야합니다. 그러나 빌더 패턴은 복잡한 객체를 생성하기위한 간단한 단계별 프로세스를 제공함으로써 구축 프로세스를 단순화합니다.

팁 :

  1. 정적 중첩 빌더 클래스를 제공하십시오.
  2. 객체의 필수 속성에 대한 생성자를 제공합니다.
  3. object의 옵션 속성에 대한 setter 및 getter 메서드를 제공합니다.
  4. 선택적 속성을 설정 한 후 동일한 Builder 오브젝트를 리턴하십시오.
  5. 복잡한 객체를 반환하는 build () 메소드 제공

코드 스 니펫 :

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("[email protected]","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):[email protected]:1111111111:2222222222

설명:

  1. FaceBookUser 는 composition을 사용하여 아래의 속성을 가진 복합 객체입니다.

    String userName;
    UserBasicInfo userInfo;
    ContactInfo contactInfo;
    
  2. FaceBookUserBuilder 포함하고 빌드 정적 빌더 클래스입니다 FaceBookUser .

  3. userNameFaceBookUser 를 빌드하기위한 필수 매개 변수입니다.

  4. FaceBookUserBuilder 빌드 FaceBookUser : 선택적 매개 변수를 설정하여 UserBasicInfoContactInfo

  5. 이 예제는 Builder에서 빌드 된 서로 다른 속성을 가진 세 가지 FaceBookUsers를 보여줍니다.

    1. fbUser1은 userName 속성으로 만 FaceBookUser로 작성되었습니다.
    2. fbUser2는 userName 및 UserBasicInfo로 FaceBookUser로 제작되었습니다.
    3. fbUser3은 userName, UserBasicInfo 및 ContactInfo로 FaceBookUser로 제작되었습니다.

위의 예에서는 Builder 클래스의 FaceBookUser의 모든 속성을 복제하는 대신 composition이 사용되었습니다.

창조적 인 패턴에서는 FactoryMethod 와 같은 간단한 패턴으로 시작하여 AbstractFactoryBuilder 와 같이보다 유연하고 복잡한 패턴으로 이동합니다.

Java / Lombok

import lombok.Builder;

@Builder
public class Email {

    private String to;
    private String from;
    private String subject;
    private String body;

}

사용 예 :

Email.builder().to("[email protected]")
        .from("[email protected]")
        .subject("Email subject")
        .body("Email content")
        .build();

Java 8 람다 식으로 고급 작성자 패턴

public class Person {
private final String salutation;
private final String firstName;
private final String middleName;
private final String lastName;
private final String suffix;
private final Address address;
private final boolean isFemale;
private final boolean isEmployed;
private final boolean isHomewOwner;

public Person(String salutation, String firstName, String middleName, String lastName, String suffix, Address address, boolean isFemale, boolean isEmployed, boolean isHomewOwner) {
    this.salutation = salutation;
    this.firstName = firstName;
    this.middleName = middleName;
    this.lastName = lastName;
    this.suffix = suffix;
    this.address = address;
    this.isFemale = isFemale;
    this.isEmployed = isEmployed;
    this.isHomewOwner = isHomewOwner;
 }
}

옛날 방식

public class PersonBuilder {
private String salutation;
private String firstName;
private String middleName;
private String lastName;
private String suffix;
private Address address;
private boolean isFemale;
private boolean isEmployed;
private boolean isHomewOwner;

public PersonBuilder withSalutation(String salutation) {
    this.salutation = salutation;
    return this;
}

public PersonBuilder withFirstName(String firstName) {
    this.firstName = firstName;
    return this;
}

public PersonBuilder withMiddleName(String middleName) {
    this.middleName = middleName;
    return this;
}

public PersonBuilder withLastName(String lastName) {
    this.lastName = lastName;
    return this;
}

public PersonBuilder withSuffix(String suffix) {
    this.suffix = suffix;
    return this;
}

public PersonBuilder withAddress(Address address) {
    this.address = address;
    return this;
}

public PersonBuilder withIsFemale(boolean isFemale) {
    this.isFemale = isFemale;
    return this;
}

public PersonBuilder withIsEmployed(boolean isEmployed) {
    this.isEmployed = isEmployed;
    return this;
}

public PersonBuilder withIsHomewOwner(boolean isHomewOwner) {
    this.isHomewOwner = isHomewOwner;
    return this;
}

public Person createPerson() {
    return new Person(salutation, firstName, middleName, lastName, suffix, address, isFemale, isEmployed, isHomewOwner);
}

고급 방법 :

public class PersonBuilder {
public String salutation;
public String firstName;
public String middleName;
public String lastName;
public String suffix;
public Address address;
public boolean isFemale;
public boolean isEmployed;
public boolean isHomewOwner;

public PersonBuilder with(
        Consumer<PersonBuilder> builderFunction) {
    builderFunction.accept(this);
    return this;
}


public Person createPerson() {
    return new Person(salutation, firstName, middleName,
            lastName, suffix, address, isFemale,
            isEmployed, isHomewOwner);
}

}

용법:

Person person = new PersonBuilder()
    .with($ -> {
        $.salutation = "Mr.";
        $.firstName = "John";
        $.lastName = "Doe";
        $.isFemale = false;
        $.isHomewOwner = true;
        $.address =
            new PersonBuilder.AddressBuilder()
                .with($_address -> {
                    $_address.city = "Pune";
                    $_address.state = "MH";
                    $_address.pin = "411001";
                }).createAddress();
    })
    .createPerson();

참조 : https://medium.com/beingprofessional/think-functional-advanced-builder-pattern-using-lambda-284714b85ed5#.d9sryx3g9



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow