본문 바로가기

Clean Code

관심사 분리 패턴 #10

관심사 분리

소프트웨어는 (애플리케이션 객체를 제작하고 의존성을 서로 '연결'하는) 준비과정과 (준비 과정에 이어지는) 런타임 로직을 분리해야 한다.

객체의 생성과 객체를 사용하는 부분을 분리한다.

시작에 대한 관심사 분리

  • 시작 단계는 모든 애플리케이션이 풀어야 할 관심사다.
  • main 함수에서 시스템에 필요한 객체를 생성한 후 애플리케이션에 넘긴다.
  • 애플리케이션은 그저 만들어진 객체를 사용한다.
  • 모든 객체가 생성되었다고 가정하고, 객체를 이용한 개발에 집중할 수 있다.

요청에 대한 관심사 분리

Spring 프레임워크를 통해 요청에 대한 관심사를 분리해 요청 처리에 대한 비즈니스 로직에 집중할 수 있다.

 

Servlet Filter

서블릿 필터는 DispatcherServlet 이전에 실행이 되는데 요청 내용을 변경하거나, 요청을 처리하기 전에 작업을 수행할 수 있다. 

Filter와 Interceptior는 Servlet 단위에서 실행된다. 반면 AOP는 메서드 앞에서 Proxy 패턴으로 실행된다.

 

Interceptor

인터셉터는 여러 개를 사용할 수 있고, 로그인 처리, 권한 체크, 프로그램 실행시간 계산 작업, 로그 확인 등의 업무처리에 활용된다.

 

AOP

AOP는 메서드 앞에서 Proxy 패턴으로 실행된다. 주로 '로깅', '트랜잭션', '에러 처리' 등 비즈니스 단위 메서드에서 조금 더 세밀하게 조정하고 싶을 때 사용한다. AOP는 주소, 파라미터, 애노테이션 등 다양한 방법으로 대상을 지정할 수 있다.

의존성 주입 (Dependency Injection)

객체 의존성을 DI 컨테이너에 맡긴다.

 

  • Setter 메소드 or 생성자 인수를 통해 의존성을 주입한다.
  • DI 컨테이너는 요청이 들어올 때 필요한 객체의 인스턴스를 만든 후 의존성을 설정한다.
  • 예시: Spring IOC Container

Spring IoC Container

객체 의존성을 DI 컨테이너에 맡긴다 (제어의 역전)

필요한 의존성을 알아서 넣어주기 때문에 개발자 입장에선 비즈니스 로직에 집중할 수 있다.

Cross Cutting Concerns 분리

애플리케이션 전반에서 가지는 공통적인 관심사를 분리한다.

  • 비즈니스 로직 외에 Logging, Transaction 관리, Security 등 신경 써야 할 관심사들이 있다.
  • 관심사들은 많은 어플리케이션 레이어에 퍼져있는데, 이 관심사들을 분리해 처리하는 것이 효율적이다.
public Response executeBusinessLoginc(Request request) {
    // 공통 기능
    CheckAuth(request)
    
    // 비즈니스 로직
    Response response = businessLogic(userName, message);
    
    // 공통 기능
    logging(response);
}

// ==> 아래와 같이 수정

public Response executeBusinessLoginc(Request request) {
    // 비즈니스 로직
    Response response = businessLogic(userName, message);
}

// 공통 기능은 별도의 코드에서 관리한다.