
제작은 사용과 아주 다르다는 사실을 명심한다.
소프트웨어 시스템은 런타임 로직을 분리해야한다.
시작 단계는 모든 애플리케이션이 풀어야할 관심사다. 관심사 분리는 우리 분야에서 가장 오래되고 가장 중요한 설계 기법중 하나다.
체계적이고 탄탄한 시스템을 만들고 싶다면 흔히 쓰는 좀스럽고 손쉬운 기법으로 모듈성을 깨서는 절대로 안된다.
Main 분리
시스템 생성과 시스템 사용을 분리하는 방법이다.
의존성 주입
사용과 제작을 분리하는 강력한 메커니즘 하나가 의존성 주입이다.
의존성 주입은 제어 역전 기법을 의존성 관리에 적용한 메커니즘이다.
제어 역전에서는 한 객체가 맡은 보조 책임을 새로운 객체에게 전적으로 떠넘기다. 새로운 객체는 넘겨받은 책임만 맡으므로 단일 책임 원칙을 지키게 된다.
호출되는 객체는 실제로 반환되는 객체의 유형을 제어하지 않는다. 대신 호출하는 객체는 의존성을 능동적으로 해결한다.
진정한 의존성 주입은 클래스가 의존성을 해결하려 시도하지 않으며 수동적이다. 대신에 의존성을 주입하는 방법으로 설정자 메서드나 생성자 인수를 제공한다.
깨끗한 코드는 코드 수준에서 시스템을 조정하고 확장하기 쉽게 만든다.
소프트웨어 시스템은 물리적인 시스템과 다르다. 관심사를 적절히 분리해 관리한다면 소프트웨어 아키텍처는 점진적으로 발전할 수 있다.
횡단 관심사
EJB2 아키텍처는 일부 영역에서 관심사를 거의 완벽하게 분리한다.
영속성과 같은 관심사는 애플리케이션의 자연스러운 객체 경계를 넘나드는 경향이 잇다.
AOP는 횡단 관심사에 대처해 모듈성을 확보하는 일반적인 방법론이다.
AOP에서 관점이라는 모듈 구성 개념은 특정 관심사를 지원하려면 시스템에서 특정 지점들이 동작하는 방식을 일관성 있게 바꿔야한다라고 명시한다.
단순한 상황에 적합하다. 개별 객체나 클래스에서 메서드 호출을 감싸는 경우가 좋은 예다
프록시를 사용하면 깨끗한 코드를 작성하기 어렵다
다행스럽게도 대부분의 프록시 코드는 판박이라 도구로 자동화할 수 있다.
순수 자바 관점을 구현하는 스프링 AOP, JBoss AOP 등과 같은 여러 자바 프레임워크는 내부적으로 프록시를 사용한다.
스프링은 비즈니스 논리를 POJO로 구현한다. POJO는 순수하게 도메인에 초점을 맞춘다.
프로그래머는 설정 파일이나 API를 사용해 필수적인 애플리케이션 기반 구조를 구현한다.
관심사를 관점으로 분리하는 가장 강력한 도구는 AspectJ 언어다.
언어 차원에서 관점을 모듈화 구성으로 지원하는 자바 언어 확장이다.
관점을 분리하는 강력하고 풍부한 도구 집합을 제공하긴 하지만, 새 도구를 사용하고 새 언어 문법과 사용법을 익혀야 한다는 단점이 있다.
코드 수준에서 아키텍처 관심사를 분리할 수 있다면 진정한 테스트 주도 아키텍처 구축이 가능해진다.
아주 단순하면서도 멋지게 분리된 아키텍처로 소프트웨어 프로젝트를 진행해 결과물을 재빨리 출시한 후, 기반 구조를 추가하며 조금씩 확장해 나가도 괜찮다는 말이다. 그렇다고 아무 방향 없이 프로젝트에 뛰어들어도 좋다는 소리는 아니다.
시스템의 일반적인 구조도 생각해야한다.
모듈을 나누고 관심사를 분리하면 지엽적인 관리와 결정이 가능해진다.
가장 적합한 사람에게 책임을 맡기면 가장 좋다. 우리는 때때로 가능한 마지막 순간까지 결정을 미루는 방법이 최선이라는 사실을 까먹곤한다.
아주 과장되게 포장된 표준에 집착하는 바람에 고객 가치가 뒷전으로 밀려난 사례를 많이 봤다.
DSL은 간단한 스크립트 언어나 표준 언어로 구현한 API를 가르킨다.
DSL로 짠 코드는 도메인 전문가가 작성한 구조적인 산문처럼 읽힌다.
좋은 DSL은 도메인 개념과 그 개념을 구현한 코드 사이에 존재하는 의사소통 간극을 줄여준다.
시스템 역시 깨끗해야한다. 깨끗하지 못한 아키텍처는 도메인 논리를 흐리며 기민성을 떨어뜨린다.
시스템을 설계하든 개별 모듈을 설계하든, 실제로 돌아가는 가장 단순한 수단을 사용해야한다는 사실을 명심하자