[Diary] 지저분한 Service 메서드 코드 Command DesignPattern 적용기
본문 바로가기

Development/Diary

[Diary] 지저분한 Service 메서드 코드 Command DesignPattern 적용기

이 글에서는 설문조사 웹 애플리케이션 개발 프로젝트에서 서비스 레이어 메서드의 로직이 가독성이 떨어지고, 유지보수가 어려운 상황을 개선하기 위해 Command 디자인 패턴을 적용한 경험을 공유하고자 합니다.

Command 패턴

Command 패턴은 행동 패턴 중 하나로, 요청을 객체의 형태로 캡슐화하여 여러 가지 다른 요청이 나중에 필요할 때 실행되거나 취소될 수 있도록 하는 패턴이다. 이 패턴을 사용하면 요청하는 객체와 요청을 수행하는 객체 사이의 결합을 느슨하게 만들 수 있다.

Command 패턴의 핵심 아이디어는 작업을 요청하는 객체를 독립적으로 처리할 수 있게 하는 것이다.

Command 패턴의 구성 요소

https://images.velog.io/images/ayoung0073/post/3f6fbd8a-61d1-4bee-b4d7-aac07238234c/image.png

  1. Command 인터페이스:
    • 실행될 동작을 정의하는 인터페이스이다. 일반적으로 execute() 메서드를 포함한다.
  2. ConcreteCommand 클래스:
    • Command 인터페이스를 구현하며, 실제 동작을 수행하는 클래스이다. 여기에는 요청을 처리할 수신자(Receiver)가 포함된다.
    • 요청을 처리하는 로직을 execute() 메서드에 구현한다.
  3. Receiver 클래스:
    • 실제 요청을 처리하는 작업을 수행하는 클래스이다. ConcreteCommand 클래스는 Receiver 객체를 호출하여 요청을 처리한다.
  4. Invoker 클래스:
    • Command 객체를 실행하는 클래스이다. 이 클래스는 하나 이상의 Command 객체를 저장하고 있다가 필요할 때 execute() 메서드를 호출한다.

Command 패턴 적용하기

기존 코드의 문제점

너무 길어서 짤려버린 코드...

설문조사에 응답 데이터를 저장하기 위해서는 대략 이런 순서로 진행이 된다.

  1. 응답한 설문조사에 해당하는 설문조사 엔티티를 불러온다.
  2. 응답한 질문에 해당하는 질문 엔티티를 불러온다.
  3. 응답의 유형(e.g. 단답형, 객관식)에 따라 응답 엔티티를 생성하고 저장한다.
  4. 응답에 따른 보상 포인트를 계산하고 저장한다.

위 모든 비즈니스 로직을 한 메서드에 직접 구현했다. 한 메서드 내에 너무 많은 작업이 집중되면서 코드가 복잡해졌고 가독성이 떨어졌다.

위 문제를 해결하기 위해 Command 디자인 패턴을 적용했다.

1. Command 인터페이스 정의

public interface Command {
    void execute();
}

2. Invoker 클래스 정의

@Service
@RequiredArgsConstructor
public class CommandExecutor {

    private final List<Command> commands;

    public void executeCommands() {
        for (Command command : commands) {
            command.execute();
        }
    }
}

3. Concrete Command 객체들 정의

기존에 한 메서드에서 수행하던 로직을 여러 Command 클래스를 만들어서 분리시켰다.

4. Receiver 메서드 리팩토링

Command 패턴을 적용하여 리팩토링한 createAnswer 메서드

효과

Command 패턴을 적용함으로써 얻은 효과는 다음과 같다:

  1. 책임 분리: 각 Command 클래스 별 책임을 분리하여, 코드의 가독성이 크게 향상되었다.
  2. 복잡성 관리: 복잡한 로직을 여러 개의 작은 클래스로 나누어 관리하여 코드의 복잡성을 줄였다.
  3. 유지보수성 향상: 코드가 명확하게 분리되어 있어 수정 시 영향 범위를 최소화할 수 있다.

마치며

  • Command 패턴은 코드의 가독성, 유지보수성, 재사용성을 높이는 데 유용한 디자인 패턴이다.
  • 그러나 Command 패턴을 적용하면 클래스와 객체의 수가 증가한다. 과도한 Command 클래스 생성을 피하고, 필요에 따라 적절한 수준으로 적용하는 것이 좋다. 단순한 작업에는 오버헤드가 될 수 있으므로 신중하게 사용한다.