빌더 패턴은 무엇일까?
자바를 사용하다 보면 build라는 어노테이션이나 http build 한다는 표현을 본 적이 있다.
이처럼 속성을 빌딩하는 형식으로 보기 좋게 클래스를 생성하는 걸까
빌더 패턴은 복잡한 객체를 생성할 때 사용하는 디자인 패턴이다. 일반적으로 객체가 생성할 때 생성자에 많은 파라미터를 전달해야 하거나, 객체의 속성들이 많을 경우 가독성과 유지보수가 어려워 질 수 있다. 빌더 패턴은 이러한 문제를 해결하기 위해 객체 생성 과정을 단계별로 분리하여, 각 송성을 명시적으로 설정할 수 있다.
객체의 속성이 많거나 생성자의 파라미터가 많으면 코드가 한번에 알아보기 어려울 수 있다.
이를 객체를 단계적으로 생성과정을 나누어 속성을 명시함으로써 해결하기 위해 빌더 패턴이 존재한다.
이 패턴을 사용하면 객체를 만들 때 각 속성을 단계별로 설정하면서, 객체가 완성될 때까지 유연하게 조정할 수 있다. 또한 불필요한 생성자 오버로딩을 줄이고, 객체의 가독성을 높여 원하는 기능이 제대로 작동하는지 쉽게 확인할 수 있다.
생성자 오버로딩이 불필요하게 많아지면 코드가 지저분해지므로 이를 막는 장점도 있다.
빌더 패턴을 Java에서 실습해보자
public class User {
private final String firstName;
private final String lastName;
private final int age;
private final String phone;
private final String address;
private User(UserBuilder builder) {
this.firstname = builder.firstName;
this.lastName = builder.lastName;
this.age = builder.age;
this.phone = builder.phone;
this.address = builder.address;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public String getPhone() {
return phone;
}
public String getAddress() {
return address;
}
public static class UserBuilder {
private final String firstName;
private fianl STring lastName;
private int age;
private String phone;
private String address;
public UserBuilder(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public UserBuilder age(int age) {
this.age = age;
return this.
}
public UserBuilder phone(String phone) {
this.phone = phone;
return this;
}
public UserBuilder address(String address) {
this.address = address;
return this;
}
public User build() {
return new User(this);
}
}
public String toString() {
return "User: " + this.firstName + " " + this.lastName + ", Age: " + this.age
+ ", Phone: " + this.phone + ", Address: " + this.address;
}
}
User라는 클래스 안에 static UserBuilder 클래스를 작성하고 각 멤버 변수를 설정하는 멤버 함수들을 작성한다.
public class Main {
public static void main(String[] args) {
User user1 = new User.UserBuilder("John", "Doe).build();
User user2 = new User.UserBuilder("Jane", "Doe)
.age(30)
.phone("123-456-7890")
.address("123 Main St")
.build();
System.out.println(user1);
System.out.println(user2);
}
}
UserBuilder는 User 객체를 단계적으로 생성하게 하고 필수 속성으로 firstName과 lastName을 설정해야 한다. 그리고 선택적인 속성들은 각 메서드를 통해 설정되고 이후 build()메서드를 호출해서 User객체를 생성한다.
이처럼 두 개의 User클래스의 인스턴스를 생성하지만 필수적인 속성을 필요로 하는 생성자이외는 빌더 패턴으로 속성들을 설정할 수 있다. 이를 통해 생성자 오버로딩을 피하고 가독성 높은 코드가 완성이 된다.
spring boot에서 securityFilter를 설정할 때 요구되는 메서드들이 이러한 원리로 작성됨을 알게 되었다.
"이 글의 내용은 OpenAI의 ChatGPT를 참고하여 작성되었습니다."