템플릿 메서드 패턴과 전략 패턴의 실제 적용과 개선

궁금하면 500원·2024년 7월 26일
0

토비님의 스프링 강의에서 템플릿 메서드 패턴과 전략 패턴을 학습하고, 사이드에서 적용해보았습니다.

public abstract class AuthStrategyImpl implements AuthStrategy {
    ...

    @Override
    public void execute(final Long adminId, final String apiTokenUuid, final Object resourceId,
        final AccessLevelType accessLevelType) {
        final List<Long> placeIds = this.get...(this.getPlaceId(resourceId),
            accessLevelType);
        ...
    }

    protected abstract Long getPlaceId(Object resourceId);

    private List<Long> getPlace...(final Long placeId,
        final AccessLevelType accessLevelType) {
        return this.placeRepository.find...(placeId).map(
            parents -> {...}
        ).orElseThrow(() -> new PermissionDeniedException("Place not found"));
    }
}

제 의도는 execute 를 구현하는 클래스를 여러 개 생성하여 갈아끼우는 방식이었습니다.

근데 설계를 해놓고 나니 정작 execute 부분은 변동이 없었습니다.

오히려 getPlaceId 부분이 각 클래스마다 변경되는 것 같아서,
하나의 추상 클래스로 execute 를 통합하고 추상 클래스를 상속받는 각 구현체에서
getPlaceId 를 구현하도록 했습니다.

이렇게 하다 보니 나는 분명 템플릿 메서드 패턴 & 전략 패턴으로 아키텍처를 설계했다고 생각했는데,
execute 가 바뀌는 대상이 아니라 getPlaceId 가 바뀌는 대상이 되면서
그냥 전형적인 템플릿 메서드 패턴이 되었습니다.

그래서, getPlaceId 를 분리하여 이 부분을 extractor 로 규정하고 개별 클래스로 분리하였습니다.
AuthStrategyImpl 는 그냥 하나의 AuthorizeExecutor 가 되었고,
PlaceIdExtractor 인터페이스를 활용하여 PlaceId 를 추출하는 형태로 개선되었습니다.

어떤 부분이 변동이 없는 부분이고 어떤 부분이 구현이 필요한 부분인지를 명확하게
진단하지 못한 저의 짧은 생각이었습니다.

하지만 이런 실수를 겪으면서 좀 더 손에 익는것 아닐까 그런생각이 듭니다.
아키텍처는 어렵기 때문에 역시 적용 훈련이 필요한 거 같습니다.

profile
꾸준히, 의미있는 사이드 프로젝트 경험과 문제해결 과정을 기록하기 위한 공간입니다.

0개의 댓글