클린 코딩은 낮은 추상화(abstraction) 단계에서의 모듈화와 관심분리(separation of concerns)에 도움을 준다. 그렇다면 높은 추상화 즉 시스템 단계에서의 모듈화와 관심분리는 어떻게 구현할 수 있을까?
시스템 실행(startup)과 시스템 사용(use)을 구분하라.
안티패턴 예시
시스템 실행은 그 자체로 하나의 관심(concern)이다. 관심분리의 원칙에 따라 시스템 실행은 당연히 어플리케이션의 다른 관심들로부터 분리되어야 한다. 다음 예를 보자.
class Controller {
service: Service | null = null;
getService(): Service {
if (this.service === null){
this.service = new ServiceImpl(...constructorArgs);
return this.service;
}
}
}
장점
getService 함수가 실제로 실행되기 전까지는 ServiceImpl을 생성하지 않으므로 불필요한 메모리 사용을 아낄 수 있고 어플리케이션 실행 속도도 빨라진다.
null 체크를 통해 this.service가 null을 반환하는 것을 방지한다.
단점
Controller가 ServiceImpl의 생성에 직접적으로 의존한다.
실제 ServiceImpl가 런타임에서 사용되지 않더라도 컴파일 단계에서 의존성을 갖는다.
ServiceImpl의 생성이 런타임 로직과 결합되어 테스트가 어렵다.
위의 예시와 같은 lazy init은 어플리케이션의 모듈화를 저해하고 SRP에 위배된다
main 함수를 통한 실행과 사용 분리
시스템 실행을 담당하는 main 함수 만들어라. main 함수는 런타임 시 필요한 인스턴스들을 생성하는 역할을 한다.
생성해야하는 인스턴스 타입이 런타임에 결정되는 경우 Abstract Factory 패턴으로 해결할 수 있다.
의존성 주입을 통한 실행과 사용 분리
IoC(Inversion of Control)는 어떤 오브젝트가 갖고 있는 부차적인 기능을 해당 기능만을 전문적으로 담당하는 다른 오브젝트에게 전가시킴으로써 SRP를 달성하는 기법이다.
Dependency Injection은 IoC를 의존성 관리에 적용시킨 것이다. 즉, 어떤 오브젝트의 의존성들을 인스턴스화하는 기능을 다른 오브젝트에게 맡기는 것을 DI라고 한다.
DI를 가능케 하는 세 가지 핵심 요소
의존성 관계를 설정하기 위한 configuration
의존성을 넘겨 받을 수 있는 setter 혹은 생성자
의존성을 주입하는 컨테이너
확장 가능한 시스템을 만들어라
안티패턴 예시
EJB(Enterprise JavaBeans)
EJB는 대형 어플리케이션을 위해 고안된 설계 스펙이다. 구성 요소는 아래와 같다.
Chapter 11 System
도입
클린 코딩은 낮은 추상화(abstraction) 단계에서의 모듈화와 관심분리(separation of concerns)에 도움을 준다. 그렇다면 높은 추상화 즉 시스템 단계에서의 모듈화와 관심분리는 어떻게 구현할 수 있을까?
시스템 실행(startup)과 시스템 사용(use)을 구분하라.
시스템 실행은 그 자체로 하나의 관심(concern)이다. 관심분리의 원칙에 따라 시스템 실행은 당연히 어플리케이션의 다른 관심들로부터 분리되어야 한다. 다음 예를 보자.
장점
단점
위의 예시와 같은 lazy init은 어플리케이션의 모듈화를 저해하고 SRP에 위배된다
확장 가능한 시스템을 만들어라
안티패턴 예시
EJB Local/Remote Interface
클라이언트가 EJB 어플리케이션를 사용하기 위해 필요한 API를 제공
**EJB Entity Bean**
관계형 데이터베이스의 레코드를 메모리 상에 로드하기 위한 클래스
**EJB Local/Remote Home Interface**
클라이언트가 EJB Bean을 생성, 제거, 검색할 수 있는 API를 제공
****XML 파일****
데이터베이스 테이블과 Entity Bean 클래스의 프로퍼티를 매핑하고, 트랜스액션 정책, 보안 정책 등을 설정하기 위한 파일
EJB 디자인의 문제점
확장 가능한 시스템의 장점 및 주의점