728x90
✍️ 학습 목표
- 객체 생성하기 (feat. 생성자)
- 각각의 장단점 이해하기
📌 객체 생성하기 (feat. 생성자)
생성자를 사용해서 객체를 사용하는 방법은 3가지가 존재한다.
각 방식의 사용법들은 다음과 같다.
1️⃣ 점층적 생성자
매개변수가 다른 생성자를 여러 개 구현하는 방식이다.
필수 매개변수가 들어가는 생성자부터 선택 매개변수를 하나하나 추가되는 생성자를 점층적으로 구현하는 방식이다.
class Pokemon {
private final int attack, defense, hp;
public Pokemon(int attack) {
this(attack, 0, 0);
}
public Pokemon(int attack, int defense) {
this(attack, defense, 0);
}
public Pokemon(int attack, int defense, int hp) {
this.attack = attack;
this.defense = defense;
this.hp = hp;
}
}
- 매개 변수가 많아지면 구현해야할 생성자의 수가 늘어난다.
- 매개 변수가 많아지면 클라이언트 코드를 작성하거나 읽기 어렵고, 실수에 취약하다.
2️⃣ 자바빈스 패턴
매개변수가 없는 생성자로 객체를 만들고 세터를 사용하는 방식이다.
class Pokemon {
private int attack = 0;
private int defense = 0;
private int hp = 0;
public Pokemon() { };
public void setAttack(int attack) { this.attack = attack; }
public void setDefense(int defense) { this.defense = defense; }
public void setHp(int hp) { this.hp = hp; }
}
- 객체 하나를 위해서 많은 메소드들을 호출해야 한다.
- 객체가 완성되기 전에는 일관성이 무너진 상태이다. (setter로 속성이 계속 변할 수 있는 상태)
- 따라서 클래스를 불변의 상태로 만들 수 없고 스레드 안정성 또한 보장되지 않는다.
- 이런 단점을 보완하기 위해서 객체를 얼리는 방법도 있지만 추천되는 방법이 아니다.
3️⃣ Builder 패턴
클라이언트가 직접 필요한 객체를 구성하는 대신 정말 필요한 매개변수로만 생성자를 호출하는 방식이다.
class Pokemon {
private final int attack, defense, hp, speed;
static class Builder {
private final int attack, defense, hp; // 필수 매개변수
private int speed = 5; // 선택 매개변수 - 기본값으로 초기화
public Builder(int attack, int defense, int hp) {
this.attack = attack;
this.defense = defense;
this.hp = hp;
}
public Builder speed(int val) {
speed = val;
return this;
}
public Pokemon build() {
return new Pokemon(this);
}
}
private Pokemon(Builder builder) {
attack = builder.attack;
defense = builder.defense;
hp = builder.hp;
speed = builder.speed;
}
}
public class BuilderPattern {
public static void main(String[] ars) {
Pokemon 피카츄 = new Pokemon.Builder(5, 5, 5).build();
// 꼬부기는 속도가 느리다..!
Pokemon 꼬부기 = new Pokemon.Builder(5, 5, 5).speed(0).build();
}
}
- 세터 메서드들을 연쇄적으로 호출해서 직관적으로 객체를 생성할 수 있다.
- 외부에서 생성된 객체를 수정할 수 없고, build() 로 객체의 생성을 명시하기 때문에 불변성을 보장할 수 있다.
빌더 패턴은 계층적으로 설계된 클래스에서 사용하기 좋은데, 하위 클래스의 조건에 맞게 변경할 수 있기 때문이다.
😋 정리
Builder 패턴은 생성하는 객체의 불변성을 보장할 수 있고, 매우 유연한 방식이다.
하지만 무조건적으로 좋은 것은 아니므로 생성자의 매개변수가 많다면 사용을 고려해 보자!
'개인 공부 > Java (이펙티브 자바)' 카테고리의 다른 글
[이펙티브 자바] 아이템 6 : 불필요한 객체 생성을 피하라 (0) | 2023.01.15 |
---|---|
[이펙티브 자바] 아이템 5 : 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) | 2023.01.15 |
[이펙티브 자바] 아이템 4 : 인스턴스화를 막으려거든 private 생성자를 사용하라 (0) | 2023.01.02 |
[이펙티브 자바] 아이템 3 : private 생성자나 열거 타입으로 싱글턴임을 보증하라 (0) | 2022.12.21 |
[이펙티브 자바] 아이템 1 : 생성자 대신 정적 팩토리 메서드를 고려하라 (0) | 2022.12.07 |
댓글