[백엔드] 단순 가독성 향상을 넘어선 Clean Architecturing의 요소 - Patterns

Hyo Kyun Lee·2025년 12월 25일

백엔드

목록 보기
32/33

1. 개요

Spring batch의 itemReader/itemWriter의 itemStream 구현형태, 목적에 대해 분석하면서 template method, factory 패턴이 많은 부분에 적용되어있음을 확인할 수 있었다.

일전에 전략패턴과 팩토리패턴을 자동화 체계 구축에 활용한 적이 있었는데, Spring Batch에서도 이러한 패턴을 많은 곳에 적용한 것을 보면서 패턴의 중요성을 다시 한번 느끼게 되었다.

특히 단순히 가독성을 향상할 수 있는 방법이 아닌, 프로젝트의 안전성이나 유지관리성을 향상할 수 있는 Clean Architecturing 요소로 바라보는 것이 맞고, 그만큼 중요도가 높은 개념이기에 한번 되짚고 넘어가는 것이 좋겠다는 생각이 들었다.

간단하지만 재미있고 활용도가 높은 pattern에 대해 정리해보겠다.

(*추가적인 pattern 요소를 알게된다면 추가 벨로그 글을 작성하여 기술할 예정)

2. Template method pattern

template method pattern의 요소는 부모클래스(abstract)를 지정하고, 어떠한 흐름/과정에 대해 추상 메서드로 정의를 해놓는것이다.

즉, 말마따나 하나의 설계도(method)를 제공하는 방안으로 template method pattern을 고려해볼 수 있겠다.

전체 절차는 정해져 있지만, 세부 단계만 경우에 따라 다를 때 사용하는 template method pattern을 적용함으로써 공통로직의 중복을 제거하고, 처리흐름의 일관성을 유지할 수 있으며 유연하게 로직의 확장 및 변경을 가능하도록 한다.

abstract class BatchJobTemplate {

    // 전체 흐름 고정
    public final void execute() {
        read();
        process();
        write();
    }

    protected abstract void read();
    protected abstract void process();
    protected abstract void write();
}

예를 들어 부모클래스로 간주할 추상클래스를 만들어 놓고, 어떠한 과정/흐름으로 절차를 정의해놓을지 구성한다.

그리고 final 메서드로 고정된 "전체 흐름"을 정의해놓는다.

class OrderBatchJob extends BatchJobTemplate {
    protected void read() { System.out.println("주문 읽기"); }
    protected void process() { System.out.println("주문 처리"); }
    protected void write() { System.out.println("주문 저장"); }
}

이를 상속받아 abstract 메서드를 구현하여, 세부적인 사항들에 대해 customized하게 정의하는 것이 핵심이다.

이때 전체적인 절차(execute)는 그대로 유지가 가능하며, 세부적인 요소들에 대해 각각의 흐름을 유연하게 변경하고 구성할 수 있는 것이 template method pattern의 특징이다.

3. Strategy Pattern

Strategy pattern은 적용하고자 하는 동작/알고리즘을 객체화하여 런타임 시점에 유연하게 적용 및 교체할 수 있도록 인터페이스를 제공하는 패턴이다.

Strategy pattern의 핵심요소는 동작에 대해 인터페이스로 정의하고, 특정 시점에서 해당 인터페이스를 구현하는 특정 구현체를 지정하여 해당 객체로직으로 동작하도록 구성해주는 것이다.

이를 통해 불필요한 if/else/switch의 남용을 방지할 수 있고, 동작/알고리즘을 유연하게 교체할 수 있을 뿐만 아니라 재사용성/재활용성을 극대화할 수 있는 OOP의 관점에서 유지관리성, 편의성을 향상할 수 있는 좋은 방향이기도 하다.

interface DiscountStrategy {
    int discount(int price);
}

위와 같이 "동작"에 대해 인터페이스로 정의해놓는다.

class RateDiscount implements DiscountStrategy {
    public int discount(int price) {
        return price * 90 / 100;
    }
}

이후 해당 동작을 정의하는 객체를 정의하여, 해당 인터페이스의 알고리즘을 customized한다.

class OrderService {
    private final DiscountStrategy strategy;

    OrderService(DiscountStrategy strategy) {
        this.strategy = strategy;
    }

    public int calculate(int price) {
        return strategy.discount(price);
    }
}

전략패턴의 핵심은 해당 인터페이스를 바라보다가, 런타임 시점에 그 인터페이스를 구현하는 특정 객체를 다시 바라보도록 하는 것이다.

위와 같이 service의 입장에서는 전략 인터페이스를 final화하여 동작에 대한 "적용"을 미리 지정해놓고, 이를 객체를 적용하기만 하여 "세부적인 동작"을 정의해줄 수 있기에 유지관리가 편할 수 있다.

4. Factory Pattern

factory 패턴은 전략패턴의 확장판, 어떻게 보면 adapter 형태라 볼 수 있는데, 객체를 직접 적용하는 전략패턴에서 이러한 객체를 factory 내부에 몰아넣어 보관하는 방안이 적용된 패턴이다.

사실 보관 방법에 대한 차이이지만, strategy pattern의 객체를 도메인으로 통합하여 보관하거나 프로젝트 관리 관점에서 편의성을 도모하기위해 factory pattern을 사용하기도 한다.

interface Payment {
    void pay();
}

먼저 동작/알고리즘을 전략화하여,

class CardPayment implements Payment {
    public void pay() { System.out.println("카드 결제"); }
}

이를 전략패턴처럼 객체화하는 것까지는 동일하다.

class PaymentFactory {
    static Payment create(String type) {
        if ("CARD".equals(type)) return new CardPayment();
        throw new IllegalArgumentException();
    }
}

다만 이러한 전략객체들을 하나의 factory 객체로 모아두고, 전략객체를 공급하는 말 그대로 "factory"(공급처)의 구성을 해두는 것이 factory pattern의 핵심요소이다.

5. 결론

위에서 살펴본 pattern에 대해 챗지피티에게 부탁해서 표로 간단하게 정리해보도록 하였다.

구분Template MethodStrategyFactory
핵심 목적처리 흐름 고정행위 교체객체 생성 분리
변경 대상알고리즘의 일부 단계알고리즘 전체생성할 객체 종류
구현 방식상속조합(주입)위임
실행 시 교체❌ (컴파일 시)✅ (런타임)
대표 키워드뼈대 고정전략 교체생성 책임 분리
if/else 제거부분적매우 효과적효과적
Spring 예Batch TemplateProcessor/PolicyBeanFactory

기본적으로 이러한 패턴정보들은 불필요한 분기처리를 줄이고, 동작 및 알고리즘의 뼈대를 제공하거나 객체화하여 재활용성을 강화하는 OOP 관점으로 이해해본다면 꽤 흥미로운 주제가 될 것이다.

또한 나아가, 단순 재활용성이나 가독성을 향상할 수 있는 악세서리적인 요소가 아닌 프로젝트의 유지관리성, 편의성을 상당부분 향상하고 협업적 측면을 강화할 수 있는 쉽고, 간결한, 강력한 요소가 될 수 있을 것이다.

다시 한번 정리하면,

Template Method
- 흐름은 바꾸지 않고, 내용만 바꾼다.

Strategy
- 행동 자체를 갈아 끼워라

Factory
- 누가 만들어지는지는 몰라도 된다.

위와 같다.

알면 알수록 흥미로운 주제이다.

이후에 프로젝트 유지관리, 편의성을 도모할 수 있는 추가 패턴을 분석할 기회가 생긴다면 추가적인 글을 작성하여 다시 한번 패턴에 대해 정리해보도록 하겠다.

0개의 댓글