스택큐힙리스트

팩토리 메서드 패턴 – 커맨드 객체를 ‘숨겨’ 깔끔 생성하기 본문

개발

팩토리 메서드 패턴 – 커맨드 객체를 ‘숨겨’ 깔끔 생성하기

스택큐힙리스트 2025. 7. 15. 18:36
반응형

“if‧else 지옥에서 탈출, 확장이 보인다”

 

왜 Factory Method인가?

CLI Todo 앱은 add, list, done처럼 명령(Command) 종류가 계속 늘어납니다. 매번 new AddCommand()를 직접 호출하거나 switch 분기문을 늘리면, 기능 추가 때마다 코드를 열어 수정해야 해 OCP(Open–Closed Principle)를 깨뜨리죠.
국내 인기 블로그들도 “팩토리 메서드는 객체 생성 책임을 인터페이스로 감춰 결합도를 확↓, 확장성↑ 한다”고 강조합니다


CLI Todo 앱에 적용하기

목표: 문자열로 들어온 명령어를 적절한 Command 구현체로 매핑하고, 메인 로직은 인터페이스만 바라보게 한다.

// 1️⃣ 공통 인터페이스
public interface Command {
    void execute(String[] args);
}

// 2️⃣ 구체 커맨드들
public class AddCommand   implements Command { … }
public class ListCommand  implements Command { … }
public class DoneCommand  implements Command { … }
public class HelpCommand  implements Command { … }

// 3️⃣ 팩토리 메서드
public class CommandFactory {
    private CommandFactory() {}               // 인스턴스화 금지
    public static Command of(String input) {   // Factory Method
        return switch (input) {
            case "add"  -> new AddCommand();
            case "list" -> new ListCommand();
            case "done" -> new DoneCommand();
            default     -> new HelpCommand();
        };
    }
}

// 4️⃣ 사용 예
Command cmd = CommandFactory.of(args[0]);
cmd.execute(Arrays.copyOfRange(args, 1, args.length));
  • 세부 클래스를 그냥 숨겼다: main()은 Command 타입만 다루니 구현 교체가 자유롭습니다.
  • 단일 책임: 생성 로직은 CommandFactory, 실행 로직은 각 Command가 맡아 코드가 또렷합니다.

확장 전략 3가지

  1. 하위 Factory 분리
    기능 영역이 커지면 ImportCommandFactory, ExportCommandFactory처럼 서브 팩토리로 쪼개 OCP를 더욱 지킵니다.
  2. 리플렉션/서비스 로더
    플러그인 방식으로 명령을 외부 JAR에 추가하려면 ServiceLoader<Command>를 이용해 런타임에 동적 등록.
  3. Enum + 전략 패턴
    명령 종류가 고정돼 있다면 enum CommandType { ADD(AddCommand::new)… } 형태로 분기 대신 Enum 자체가 객체 생성을 책임지게 할 수 있습니다.

장점 vs. 주의할 점

  • OCP 준수: 새 명령 클래스를 만들고 Factory에 한 줄만 추가하면 끝.
  • 테스트 용이: 팩토리가 반환하는 인터페이스를 목(mock)으로 대체해 단위 테스트가 깔끔.
  • 결합도↓: 클라이언트 코드가 구체 클래스를 모르니 DI 컨테이너 전환도 수월.

주의:

  • 클래스 수가 급격히 늘 수 있습니다. “Simple Factory → Factory Method”로 옮겨갈 적정 규모를 판단하세요.
  • 너무 복잡한 분기 로직이 팩토리에 쏠리면 또 다른 결합점이 될 수 있습니다. 상위 팩토리를 단계적으로 분리해 주세요.

실전 팁

  • 테스트 우선: JUnit에서 CommandFactory의 반환값을 인터페이스로 받으면, MockCommand 주입이 쉽습니다.
  • Spring 전환기: 스프링의 BeanFactory가 바로 Factory Method 패턴의 확장판이니, CLI → 웹으로 갈아탈 때 설계가 그대로 이어집니다.
  • 도메인 이벤트용: 실행 전‧후 훅(hook)을 Factory에 두면 로깅·트랜잭션 처리를 일괄 적용하기 좋습니다.

한 줄 정리

Factory Method 패턴은 ‘어떤 객체를 만들지’ 결정권을 팩토리에 위임해, 기능 추가가 잦은 CLI Todo 앱을 유연하고 우아하게 성장시킵니다.

반응형
Comments