AskMePlz / EffectiveJava

이펙티브자바를 공부합니다.
4 stars 4 forks source link

아이템 03. private 생성자나 열거 타입으로 싱글턴임을 보장하자 #3

Closed peacebestill0314 closed 2 years ago

minjeekang commented 2 years ago

1️⃣ p. 24 익숙한 싱글톤은 아래와 같이 명시적으로 보여서 어떻게 같은 객체만 반환하는지 이해가 되었거든요

public static Elvis getInstance() {
        if(INSTANCE == null) {
            INSTANCE = new Elvis();
        }
        return INSTANCE;
}

p. 24 Elvis.getInstance는 항사 같은 객체의 참조를 반환하므로 제2의 Elvis 인스턴스란 결코 만들어지지 않다.

이 부분을 보면서 코드3-2가 어떻게 같은 객체의 참조를 반환한다는지 설명해주세요!

leechGamer commented 2 years ago

2️⃣ p.23

타입을 인터페이스로 정의한 다음 그 인터페이스를 구현해서 만든 싱글턴이 아니라면 싱글턴 인스턴스를 가짜(mock)구현으로 대체할 수 없기 때문이다.

왜 그런지 궁금해요;

peacebestill0314 commented 2 years ago

✨ 이야기 해볼 주제

peacebestill0314 commented 2 years ago

1️⃣

public class Elvis { 
    private static final Elvis INSTANCE = new Elvis();
    private Elvis() { ... }
    public static Elvis getInstance() { return INSTANCE; } // 정적 팩토리 메서드 방식 
    public void leaveTheBuilding() { ... }
}

24p 3-2 코드에 보시면 Elvis 인스턴스를 생성 하기 위해서 정적 팩토리 메서드를 통해 객체를 반환하고 있는데 해당 메서드에서 리턴하는 인스턴스를 private static 으로 이미 생성되어 있는 하나의 같은 객체를 사용하게함으로써 같은 객체의 참조를 반환하게 하고 있습니당

peacebestill0314 commented 2 years ago

2️⃣

public class Elvis {
    private static final Elvis INSTANCE = new Elvis();
    private Elvis() { 
        this.check = 0;
    }
    public static Elvis getInstance() { return INSTANCE; }
    private int check;
    public void leaveTheBuilding(int num) {
        if(num > check) {
            throw new IllegalArgumentException();
        }
    }
}

위에 3-2 코드를 조금 변형해서 보면 해당 싱글턴 인스턴스의 leaveTheBuilding 메서드를 테스트 할때 check 값을 변경하고 싶은 경우 해당 클래스의 인스턴스는 테스트 코드 작동 전에 먼저 생성 되어 있기 때문에 값을 변경할 수 있는 mock클래스를 만들 수 가 없어요 Elvis을 인터페이스로 정의한 다음 Elvis 인터페이스를 구현해서 만들게 되면 mock클래스 에서 변형이 가능하여 테스트가 됩니다