2023-java-study / book-study

북 스터디 기록 레포지토리
0 stars 0 forks source link

[item 19] 훅(hook)을 선별하여 protected형태로 공개하자 #56

Closed NuhGnod closed 1 year ago

NuhGnod commented 1 year ago

p.123에 클래스의 내부 동작 과정 중간에 끼어들 수 있는 훅(hook)을 잘 선별하여 protected메서드 형태로 공개 라는 말이 있습니다. 저는 다음 예시로 설명한 removeRange메서드를 생각해봐도 이 훅(hook)이 그냥 클래스의내부 메서드에서 사용되는 또 다른 내부 메서드` 정도로 이해가 되었는데 혹시 다른 생각있으신가요?

gmelon commented 1 year ago

API로 공개된 public 메서드의 내부 로직 일부를 떼어내서 protected 메서드로 하위 클래스에 공개하고, 이를 상속받은 하위 클래스가 효율적으로 사용할 수 있게 재정의할 수 있도록 하라는 의미로 이해했습니다!

성능 차이 보다는 단순 구현 방식이 달라지는 예제이긴 하지만 우선 아래와 같은 경우를 생각해볼 수 있을 것 같습니다

Parent 클래스 (protected 메서드 분리 전)

public class Parent {

    private int count = 0;

    public void method() {
        List<Object> objects = new ArrayList<>();

        int localCount = 0;
        for (Object object : objects) {
            if (checkSomething(object)) {
                localCount++;
            }
        }
        count += localCount;
    }

}

Parent 클래스 (protected 메서드 분리)

public class Parent {

    private int count = 0;

    public void method() {
        List<Object> objects = new ArrayList<>();
        count += checkAndCount(objects);
    }

    protected int checkAndCount(List<Object> objects) {
        int count = 0;
        for (Object object : objects) {
            if (checkSomething(object)) {
                count++;
            }
        }
        return count;
    }

}

Child 클래스 (분리된 protected 메서드를 stream 방식으로 재정의)

public class Child extends Parent {
    @Override
    protected int checkAndCount(List<Object> objects) {
        return (int) objects.stream()
                .filter(Parent::checkSomething)
                .count();
    }
}

이렇게 하면, Child의 인스턴스가 method() 를 호출할 때 더 이상 for-loop이 아니라 stream 방식으로 count를 하게 됩니다.