@Setter와 @Builder

한민욱·2024년 6월 10일

오늘 팀 프로젝트하다가 갑자기 이게 떠올랐다.
왜 Setter와 Builder가 나뉘어져있을까?

아라보자.

@Setter 예시

@Setter
public class Person {
    private String name;
    private int age;
}
public class Person {
    private String name;
    private int age;

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
Person person = new Person();
person.setName("John");
person.setAge(30);

클래스의 필드를 변경할 수 있는 메서드를 자동으로 생성하여 코드의 간결성을 높여주는 세터

@Builder 예시

@Builder
public class Person {
    private String name;
    private int age;
}
public class Person {
    private String name;
    private int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static PersonBuilder builder() {
        return new PersonBuilder();
    }

    public static class PersonBuilder {
        private String name;
        private int age;

        PersonBuilder() {
        }

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

        public PersonBuilder age(int age) {
            this.age = age;
            return this;
        }

        public Person build() {
            return new Person(name, age);
        }

        public String toString() {
            return "Person.PersonBuilder(name=" + this.name + ", age=" + this.age + ")";
        }
    }
}
Person person = Person.builder()
                      .name("John")
                      .age(30)
                      .build();

자 이제 제가 하면서 느낀점을 말해볼게요.

따로 쓰는 이유는 Setter만 사용했을 때 Spring-data-jpa에서의 save가 update인지 insert인지 구분이 안 가서 insert에는 builder를 써주고 update에는 setter를 써줬고,
두 번째로는 Setter를 사용하고 보니 객체의 내부 상태를 쉽게 변경할 수 있어서 OCP에 위반되는 것 같아서 써줬습니당.

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class Person {
    private final String name;
    private final int age;
}

public class Main {
    public static void main(String[] args) {
        Person person = Person.builder()
                              .name("John")
                              .age(30)
                              .build();
                            

        // person.setName("Doe"); // This line will cause a compilation error
        System.out.println("Name: " + person.getName());
        System.out.println("Age: " + person.getAge());
    }
}

요로코롬하면 객체가 생성된 후에 상태도 변경되지 않으므로 OCP를 준수할 수 있죠.

하나 더 Entity에 builder를 쓰면
entity는 파라미터가 없는 디폴트 생성자를 만들어주고 builder는 파라미터가 있는 생성자를 써야하는데,
그래서 NoArgsConstructor와 AllArgsConstructor를 직접 명시해줘야 에러가 안 뜨더라구요.

결론은 Builder를 애용하고 Setter를 지양하자입니당.

profile
나날이 성장하고 싶은 백엔드 개발자

0개의 댓글