package chapter18;
/*
빌더(Builder)
: 복잡한 객체 생성을 단순화 하는 패턴
- 객체의 생성자 인수가 많을 때 가독성이 떨어지는 문제를 보완
- 체이닝 방식을 사용하여 가독성 있고 유연한 객체 생성
cf) 디자인 패턴
: 소프트웨어 공학에서 자주 발생하는 문제에 대한 재사용 가능한 해결책
>> 생성, 구조, 행위 패턴
>> 빌더 패턴은 생성 패턴에 포함
1. 빌더 패턴의 구조(구현 단계)
: 객체 생성을 담당하는 내부 클래스
2. 필수 속성 설정
: 생성자를 통한 필수 속성을 설정
3. 선택적 속성 설정
: 체이닝 방식으로 선택적 속성을 설정할 수 있는 메소드 추가
4. build 메소드
: 최종적으로 객체를 반환하는 메소드
빌더 패턴의 특징
- 가독성 & 유연성 확장
- 불변 객체 생성 가능
: 생성된 객체는 변경할 수 없는 객체로 안정성을 보장받음
*/
// == 제품 클래스 ==
class Product{
// 필수 속성
private final String name;
private final int price;
// 선택적 속성
String descriptioin;
String manufacturer;
// 1)Builder 클래스 생성
// 외부에서 직접적인 생성자 호출이 불가하다.
private Product(Builder builder) {
this.name = builder.name;
this.price = builder.price;
this.descriptioin = builder.description;
this.manufacturer = builder.manufacturer;
}
//빌더 클래스(내부 클래스)
public static class Builder{
//필수 속성
// >> final: 상수
private final String name;
private final int price;
// 선택적 속성
private String description;
private String manufacturer;
// 필수 속성을 위한 빌더 생성자
public Builder(String name, int price) {
this.name= name;
this.price= price;
}
// 선택적 속성을 위한 메소드
public Builder description(String description) {
this.description= description;
return this;
}
public Builder manufacturer(String manufacturer) {
this.manufacturer= manufacturer;
return this;
}
// 최종적으로 Product build객체 반환
public Product build() {
return new Product(this);
}
}
// 빌더 패턴에서는 getter/ setter가 필요치 않음
// public void setName(String name) {
// this.name= name;
// }
//
public String getName() {
return name;
}
}
public class Builder01 {
public static void main(String[] args) {
// 빈 제품 Product 객체를 인스턴스화
// Product product1= new Product();
// product1.setName("iPhone16");
// System.out.println(product1.getName());
// a) 필수 속성만 설정한 Product 객체 생성
Product pd1= new Product.Builder("아이폰16", 1800000).build();
// b) 선택적 속성을 설정한 Product 객체 생성
Product pd2= new Product.Builder("Galaxy S25", 1200000).description("Samsung").build();
Product pd3= new Product.Builder("motorora", 800000).description("motorora").build();
System.out.println(pd1.getName());
System.out.println(pd2.getName());
System.out.println(pd3.getName());
}
}
package chapter18;
import chapter18.Product.Builder;
/* == 빌더 패턴없이 ==
학생 클래스 구현
: name, age (필수 속성)
: grade, major (선택적 속성)
>> 생성자 4개 구현
*/
class Student{
private final String name;
private final int age;
String grade;
String major;
public Student(Builder builder) {
this.name= builder.name;
this.age= builder.age;
this.grade= builder.grade;
this.major= builder.major;
}
public String getName() {
return this.name;
}
public static class Builder{
private final String name;
private final int age;
String grade;
String major;
public Builder(String name, int age) {
this.name= name;
this.age= age;
}
public Builder grade(String grade) {
this.grade= grade;
return this;
}
public Builder major(String major) {
this.major= major;
return this;
}
public Student build() {
return new Student(this);
}
}
}
public class Builder02 {
public static void main(String[] args) {
Student st1= new Student.Builder("Gwon", 17).build();
Student st2= new Student.Builder("Hyuck", 17).grade("4").major("computer").build();
System.out.println(st1.getName());
System.out.println(st2.getName());
}
}
lombok 사용시
package chapter18;
import lombok.Builder;
import lombok.Getter;
@Builder
@Getter
class Person{
private String name;
private int age;
private String hobby;
private String favoriteFood;
/*
=== @Builder 어노테이션 ==
Person class의 내부 Builder 클래스
> name, age, hobby, favoriteFood
필드 값에 대해 모두 getter 생성
*/
}
public class Builder03 {
public static void main(String[] args) {
Person ps1= Person.builder().name("aa").build();
Person ps2= Person.builder().hobby("bb").build();
Person ps3= Person.builder().favoriteFood("cc").build();
}
}
'java' 카테고리의 다른 글
java 활용 예시(예외) (0) | 2024.09.19 |
---|---|
java활용 예시(Lambda 활용 함수) (0) | 2024.09.19 |
java활용 예시(Stream) (1) | 2024.09.13 |
java활용 예시(lambda expression) (0) | 2024.09.13 |
java 활용 예시(내부 클래스) (0) | 2024.09.13 |