Post

2025-08-27-TIL

Today I Learned

오늘은 멘토링이 있는 날이다. 이전 시간에 ACID에 대해서 깊이있는 이야기를 했는데, 관련 내용이 ‘데이터 중심 애플리케이션’의 07장 트랜잭션에 나와있다. 이 책에서 말하는 설명을 잘 읽어보면 ACID 속성의 하나하나가 더 와닿는다. 이 네 가지 속성에 대해서는 다시 한 번 정리해봐야겠다. 그리고 MongoDB 등 NoSQL에서도 지원하는데, 어떻게 지원 가능한지 구현기술을 학습해보려고 한다.

2025-08-27-Mentoring

팩토리란?

“팩토리(Factory)”라는 말은 단순히 “객체를 만들어주는 곳”이라는 뜻이다. 즉, 프로그래밍에서 new를 직접 쓰지 않고, 객체 생성을 전담하는 클래스나 메서드를 가리킨다.

현실의 공장(factory)처럼 → 재료를 넣으면 완제품이 나오는 구조이다. 개발에서 factory는 → 파라미터(조건)를 넘기면 → 적절한 객체(인스턴스)를 생성해 반환한다.

팩토리의 종류는 세 가지가 있다.

단순 팩토리(Simple Factory)

  • 정적 메서드 등을 이용해 조건에 맞는 객체를 생성한다.
  • 디자인 패턴 책(GOF)에는 포함되지 않지만, 실무에서 자주 쓰인다.
1
2
3
4
5
6
7
8
9
class ShapeFactory {
    public static Shape getShape(String type) {
        switch (type) {
            case "circle": return new Circle();
            case "square": return new Square();
            default: throw new IllegalArgumentException("Unknown type");
        }
    }
}

팩토리 메서드 패턴(Factory Method Pattern)

  • 객체 생성을 서브클래스에게 위임하는 구조.
  • createSomething() 같은 메서드를 추상화하고, 서브클래스가 실제 객체를 리턴.

추상 팩토리 패턴(Abstract Factory Pattern)

  • 관련된 객체들의 “제품군”을 생성하는 인터페이스를 제공.
  • 예: GUIFactorycreateButton(), createCheckbox() 등.

팩토리는 객체 생성 로직이 복잡하거나, 자주 변경될 가능성이 있을 때 유용하다. 클라이언트 코드가 구체 클래스(new)에 의존하지 않게 만들고 싶을 때에도 적용이 가능하다. 이는 SOLID 원칙 중에서 “확장에는 열려 있고, 수정에는 닫혀 있어야 한다”(OCP 원칙)를 지킬 때 사용된다.

팩토리(Factory)는 객체 생성을 대신해주는 “공장 역할”을 하는 클래스나 메서드이다. 결국 new를 직접 쓰는 대신, 객체 생성 책임을 한곳에 모아두는 것이다.


IoC란?

스프링에서 IoC(Inversion of Control, 제어의 역전)란 객체의 생성과 의존성 관리를 개발자가 직접 하는 대신, 스프링 컨테이너(프레임워크)가 대신 관리해주는 개념을 말한다.

IoC를 잘 구현한 곳은?

IoC를 잘 구현한다는 의미는 무엇일까?

  • 인터페이스에 의존하고, 구현 선택은 구성으로 분리한다.
  • 생성자 주입을 기본으로(필드 주입은 피함).
  • 인프라/환경 의존(데이터소스, 메시징, 캐시 등)은 컨테이너가 관리하고 필요하면 @Qualifier / @Primary로 선택.
  • 클라이언트 코드(비즈니스 로직)는 주요 책임에 집중하고, 생성/선택 책임은 외부(IoC 컨테이너)에 위임.
  • 이 구조 덕분에 확장 용이(OCP), 재사용/테스트 용이, 관심사 분리가 자연스럽게 달성됨.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Component
@RequiredArgsConstructor
public class PopularCountingInterceptor implements HandlerInterceptor {
    private final PopularCounterPort counter;

    @Override
    public void afterCompletion(@NotNull HttpServletRequest req, @NotNull HttpServletResponse res, @NotNull Object handler, Exception ex) {
        if (!(handler instanceof HandlerMethod)) return;
        if (res.getStatus() < 200 || res.getStatus() >= 300) return;

        String uri = req.getRequestURI();
        String ticker = extractTickerFromUri(uri);
        if (ticker == null) return;

        Instant now = Instant.now();
        counter.increment(ticker, PopularWindow.M15, now);
        counter.increment(ticker, PopularWindow.H1, now);
        counter.increment(ticker, PopularWindow.D1, now);
        counter.increment(ticker, PopularWindow.D7, now);
    }
}

멘토님은 프로젝트에서 PopularCountingInterceptor를 활용한 부분이 IoC를 잘 활용한 예시라고 설명해주셨다. 이 인터셉터는 시세 및 차트 조회 API의 데이터를 카운팅하도록 스프링 프레임워크에 위임한다.

스프링 컨테이너가 관리하는 @Component 빈이고, @RequiredArgsConstructor생성자 주입(불변성 보장) + 포트 인터페이스(PopularCounterPort)에 의존 → 구체 구현과 분리된 느슨한 결합(OCP 실천)이다.

This post is licensed under CC BY 4.0 by the author.