Builder패턴(디자인패턴)
빌더 패턴을 사용하면 어느 필드에 어떤 값을 채워야 할지 명확하게 알 수 있다.
스프링부트에서 자주 사용.
클래스 안에 내부클래스를 생성하고, 값을 저장함.
setter메서드와 public생성자가 없어서 처음 생성될 때 값을 지정하고 값을 변경하지 못하게 한다.
내부 클래스에는 setter메서드와 public생성자가 없기 때문에
객체를 얻기 위해서는 오직 Builder클래스를 통해서만 가능하다.
객체 불변성(Immutablity)을 보장한다.
장점: 한번 값이 지정되면 그 값은 불변한다.
단점: 설계하기가 어렵다.
※외우지 않아도 된다. 롬복의 @Builder어노테이션이 대신 해줌.
생성
내부클래스는 static일수도 아닐 수도 있다.
외부클래스와 동일한 변수를 가진다.
내부 클래스의 setter메서드가 특이하게 생겼다.
Builder클래스를 얻게 되면, set메서드를 호출할 수 있다.
set메서드로 값을 주면, 다시 Builder클래스를 반환한다.
BuilderVO.java
package com.simple.basic.command;
public class BuilderVO {
//빌더 패턴의 모형 - 내부 클래스를 생성하고, 외부에서 호출시에 내부클래스에 값을 지정
//장점-객체의 불변성(값의 변경을 막고, 사용시 가독성이 좋다.)
//1.멤버변수
private String name;
private int age;
//4.VO의 생성자
private BuilderVO(Builder builder) {
this.name=builder.name;
this.age=builder.age;
}
//7.외부에서 객체생성을 요구하면 내부에 있는 Builder클래스를 반환
public static Builder builder() {
return new Builder();
}
//2.내부클래스 생성 - 클래스 안에 클래스. inner클래스, nested클래스라고도 한다.
public static class Builder {
private String name;
private int age;
//3.생성자 제한
private Builder() {}
//5.내부 클래스에 setter메서드 생성
public Builder setName(String name) {
this.name=name;
return this;
}
public Builder setAge(int age) {
this.age=age;
return this;
}
//6. build메서드를 생성 - 나 자신을 외부클래스에 저장하고 반환
public BuilderVO build() {
return new BuilderVO(this);
}
}
//8.toString 오버라이딩
@Override
public String toString() {
return "BuilderVO [name=" + name + ", age=" + age + "]";
}
}
-순서를 보면서 이해해야 한다.
- 외부클래스(BuilderVO)에 멤버변수 생성.
- 내부클래스(Builder) 생성. 멤버변수는 외부클래스와 동일하다. static
- 내부클래스 생성자를 private으로 제한.
- 외부클래스 생성자도 private으로 제한. 동시에 내부클래스를 매개변수로 받아 멤버변수에 값을 넣는다.
- 내부클래스에 setter메서드를 멤버변수에 맞춰 생성한다. 이때 return을 this로 하여 각각 내부클래스를 반환하도록. public
- 내부클래스에 build메서드를 생성. this를 통해 외부클래스 생성자에 내부클래스를 주고 외부클래스를 반환한다. public
- 외부에서 객체생성(BuilderVO)을 요구하면 내부에 있는 Builder클래스를 반환하게 return new 내부클래스()로 하는 builder메서드 생성. public static
BootTest.java
package com.simple.basic;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.simple.basic.command.BuilderVO;
import com.simple.basic.command.BuilderVO.Builder;
import com.simple.basic.controller.HomeController;
@SpringBootTest //스프링부트 테스트 클래스
public class BootTest {
// @Autowired
// HomeController homeController;
//
// @Test
// public void testCode01() {
// System.out.println(homeController.home());
// }
//빌더패턴 객체의 사용
@Test
public void testCode02() {
// Builder xx=BuilderVO.builder();
// xx=xx.setAge(10);
// xx=xx.setName("홍길동");
// BuilderVO vo = xx.build();
BuilderVO vo = BuilderVO.builder().setAge(10).setName("홍길동").build();
System.out.println(vo.toString());
}
}
호출순서는 7번---5번의 각 setter들 호출---6번.
각각 반환이
7번:내부클래스(builder()의 반환).
5번:지정한 변수를 받은 내부클래스(setter()의 반환).
6번: 값을 다 받은 내부클래스를 생성자의 매개변수로 받아 멤버변수의 값이 지정된 외부클래스(build()의 반환).
이후 값을 변경할 수 없다.
사용했을 때 가독성이 좋다. setter들을 바로바로 확인할 수 있음.
콘솔출력문
BuilderVO [name=홍길동, age=10]
'Spring Boot' 카테고리의 다른 글
230213 Spring Boot Thymeleaf 문법-변수, 조건문, 반복문 (0) | 2023.02.13 |
---|---|
230213 Spring Boot Lombok으로 Builder패턴 만들기 (1) | 2023.02.13 |
230210 Spring Boot 개별적인 bean 생성, 테스트코드 (0) | 2023.02.10 |
230210 Spring Boot 뷰 선택-Thymleaf (0) | 2023.02.10 |
230210 Spring Boot 뷰 선택-JSP/JSTL (0) | 2023.02.10 |