상태가 Optional하다면? 빌더 패턴(Builder Pattern) 사용하기

주리링·2022년 5월 1일
0

우테코 생존기

목록 보기
7/17
post-thumbnail

안녕하세요.
이번 포스팅은 상태가 Optional할 때 생길 수 있는 문제점을 알아보고 대처 방안 중 하나인 빌더 패턴에 대해서 알아보겠습니다.

빌더 패턴(Builder Pattern)

빌더 패턴이란 생성 패턴 중에 하나로, 생성 패턴은 인스턴스를 만드는 절차를 추상화하는 패턴입니다.

빌더 패턴을 적용하기 전의 문제점

public class ChessGameEntity {

    private long id;
    private String name;
    private String password;
    private boolean isOn;
    private String teamValueOfTurn;

}

객체를 생성할 때 모든 상태 값을 알고있지 않거나, 해당 객체가 모든 상태 값을 가지지 않아도 될 때가 있습니다.
클래스는 상태가 optional하다면 어떻게 생성해야할까요?

1. 생성자에 null값을 넣게 된다.

ChessGameEntity chessGameEntity = new ChessGameEntity(1L, "juri", "1234", null, null);

생성자에는 순서가 정해져 있기 때문에 매번 생성자의 argument 순서를 고려해야합니다.
만약 알고 있는 생성자가 매번 변한다면, 굉장히 귀찮은 일이 될 것 입니다.

2. 여러개의 생성자를 생성해야한다.

public ChessGameEntity(final long id, final String name, final String password, final boolean isOn,
                           final String teamValueOfTurn) {
        this.id = id;
        this.name = name;
        this.password = password;
        this.isOn = isOn;
        this.teamValueOfTurn = teamValueOfTurn;
    }

    public ChessGameEntity(final String name, final String password, final ChessGame chessGame) {
        this.name = name;
        this.password = password;
        this.isOn = chessGame.isOn();
        this.teamValueOfTurn = chessGame.getTurn().getNow().getValue();
    }

    public ChessGameEntity(final long id, final boolean isOn, final Turn turn) {
        this.id = id;
        this.isOn = isOn;
        this.teamValueOfTurn = turn.getNow().getValue();
    }

    public ChessGameEntity(final long id, final String password) {
        this.id = id;
        this.password = password;
    }

    public ChessGameEntity(final long id, final boolean isOn) {
        this.id = id;
        this.isOn = isOn;
    }

알고 있는 상태마다 생성자를 만들 수 있습니다.
하지만 이 경우, 부생성자의 수가 생성자를 사용하기 힘들 정도로 많다면 어떤 생성자를 쓸지 고민하는 시간이 더 많이 생길 것 입니다.
또한 객체를 생성할 때 외부 의존적인 특성을 가지게 됩니다.

결국 2가지 방법의 단점은 가독성입니다.
어떤 값을 순서에 맞게 넣는지 알 수 없기 때문입니다.

빌터 패턴 사용하기

아래 예제를 통해 해결 방안인 빌더 패턴의 사용법을 알아봅시다.

public class ChessGameEntityBuilder {

    private long id;
    private String name;
    private String password;
    private boolean power;
    private String teamValueOfTurn;
    
}

생성할 클래스와 상태가 같은 Builder 클래스를 생성합니다.

public ChessGameEntityBuilder setId(final long id) {
        this.id = id;
        return this;
    }

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

    public ChessGameEntityBuilder setPassword(final String password) {
        this.password = password;
        return this;
    }

    public ChessGameEntityBuilder setPower(final boolean power) {
        this.power = power;
        return this;
    }

    public ChessGameEntityBuilder setTeamValueOfTurn(final String teamValueOfTurn) {
        this.teamValueOfTurn = teamValueOfTurn;
        return this;
    }

    public ChessGameEntity build() {
        return new ChessGameEntity(id, name, password, power, teamValueOfTurn);
    }

각 상태 값마다 setter를 만들고, Builder 클래스를 반환하도록 합니다.
그리고 build 메서드를 통해 ChessGameEntity 클래스를 만듭니다.

ChessGameEntity chessGameEntity = new ChessGameEntityBuilder()
                .setId(chessGameId)
                .setPower(false)
                .build();

빌더 패턴을 사용하면 어떤 상태 값을 주입할지 명확하게 알 수 있고, 순서를 신경쓰지 않아도 된다는 장점이 있습니다.
또한 필요한 상태 값만 주입할 수 있다는 장점이 있습니다.

profile
코딩하는 감자

0개의 댓글