참고 포스팅

생성자 패턴의 종류

1. 점층적 생성자 패턴(Telescoping Constructor Pattern)

해당 패턴의 출처는 Joshua Bloch에 의해 'Effective Java' 내에서 언급된 패턴입니다.

public class ResponseCode {
	private int status;
    private String code;
    private String message;
    
    public ExmpleCode(int status) {
    	this(status, null, null);
    }
    
    public ExmpleCode(int status, String code) {
    	this(status, code, null);
    }
    
    public ExmpleCode(int status, String code, String message) {
    	this.status = status;
        this.code = code;
        this.message = message;
    }
}

쉽게 설명하면, 초기화할 필드 갯수만큼 생성자에 매개변수를 구성하는 패턴을 말합니다. 이를 통해서, 객체를 생성하고 싶을 때에는 정의한 매개변수를 필수로 넣어줘야만 하도록 할 수 있습니다.

2. 자바 빈즈 패턴(Java Beans Pattern)

이는 별도의 생성자를 구현하지 않고, 기본 생성자로 객체를 생성해준 뒤 setter를 사용하여 객체를 구성하는 형태를 말합니다.

public class ExampleCode {
    private int status;
    private String code;
    private String message;

    public void setStatus(int status) {
        this.status = status;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

위처럼 setter를 정의한 뒤, 기본 생성자로 객체를 생성하여 setter로 값을 초기화 해줍니다.

3. 빌더 패턴(Builder Pattern)

복잡한 객체의 생성 과정을 단계별로 분리하여 구현하는 생성 디자인 패턴을 의미합니다.

// GPT 작성 예시 코드
public class ExampleCode {
    private final int status;
    private final String code;
    private final String message;

    private ExampleCode(Builder builder) {
        this.status = builder.status;
        this.code = builder.code;
        this.message = builder.message;
    }

    public int getStatus() {
        return status;
    }

    public String getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }

    public static class Builder {
        private int status;
        private String code;
        private String message;

        public Builder() {}

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

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

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

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

💡 추가 설명

@NoArgsConstructor(access = AccessLevel.PROTECTED)

  • 파라미터가 없는 생성자를 생성해주는 어노테이션을 의미하며, 무분별한 객체 생성에 대해서 한번더 체크하기 위한 수단을 의미합니다.
  • AccessLevel.PROTECTED로 사용하는 이유는 Spring에서 프록시 객체 생성 시, PRIVATE로 제한되어 있게 되면, 생성이 불가능하기 때문입니다.

위처럼 자주 사용되는 생성자 패턴으로 3가지 정도가 있는데, 이 중 사용하기에 권장하는 방식은 Builder 방식입니다.

Builder Pattern을 사용해야 하는 이유

1. 생성자 호출 시, 매개변수의 순서를 잘못입력하는 경우를 없앤다.

정층적 패턴은 생성자 호출 시, 매개변수의 순서가 다르게 입력될 수 있는 문제가 발생합니다.

public class ExampleCode {
    private int status;
    private String code;
    private String message;

    public ExampleCode(int status, String code, String message){
        this.status = status;
        this.code = code;
        this.message = message;
    }
}

위처럼 생성자가 정의되어 있을 경우, 생성자 호출 시 code와 message는 순서에 구분되어 값이 입력됩니다.

만약, 다음과 같이 순서를 바꾸어 입력해주게 된다면, 의도하지 않은 결과를 출력하게 될 수 있습니다.

이와 다르게, 빌더 패턴을 사용하게될 경우, 매개변수에 정확한 이름이 함께 구분되므로, 실수할 확률이 적어집니다.

// Builder Pattern 사용
Example exampleCode = Example.builder()
                .status(200)
                .message("성공 되었습니다.")
                .code("200")
                .build();

2. 가독성이 좋아집니다.

자바 빈즈 패턴은 객체에 setter로 모든 값을 세팅해주어야하기 때문에, 하나의 값을 실수로 빼먹고 set을 해주지 않게되면, 의도치 않게 null 값이 반환될 수 있습니다.

상대적으로 빌더패턴은 해당 필드명을 그대로 가져와 값을 입력하기 때문에, 가독성이 좋고 실수할 확률이 줄어듭니다.


이러한 이유로 인해서 Builder 패턴을 사용하는 것을 권장드립니다.

profile
백엔드 서버 엔지니어

0개의 댓글

관련 채용 정보

Powered by GraphCDN, the GraphQL CDN