자바/클린 코드

클린코드 11장 - 시스템

끄적끄적 2022. 6. 12. 16:58

도시를 설계할때에도 수도관리팀, 전력관리팀, 교통관리팀, 치안관리팀, 건축물관리팀 등 각 분야의 담당자들이 적절한 추상화와 모듈화로 일을 하기 때문에 잘 돌아갈 수 있다. 소프트웨어도 추상화와 관심사 분리를 통해 깨끗한 시스템을 유지해야 한다.

생성(Configuration) 과 사용(애플리케이션, Service) 분리
아래와 같이 서비스 사용부에서 생성까지 책임지는 소스는 아래와 같은 문제가 있다.
1. getService()에서 MyServiceImpl이라는 구체적인 객체에 의존한다.
2. 단위테스트 구현시 MyServiceImpl이 복잡한 로직이라면, Test Double 을 service에 할당해야 하는데 불가능하다.
3. service가 null일 경우와 아닐 경우 등 객체 생성에 대한 테스트도 필요하여, 생성까지 두가지 이상 책임을 진다.

  public Service getService() {
      if (service == null)
          service = new MyServiceImpl(...); // Good enough default for most cases?
      return service;
  }

이에 대한 해결책으로는 아래의 3가지 방법을 들 수 있다.
1. Main 분리 : 생성은 Main과 Builder에서 책임지고, application은 사용부만 집중한다.

2. 팩토리 : Abstract Factory 패턴을 통해 생성은 LineItemFactory에서 책임지고, OrderProcessing은 동작에만 책임을 진다.

의존성주입 : DI(Dependency Injection)을 이용해서 객체 생성의 책임은 별도의 Config와 같은 '전담' 매커니즘에서 책임지고, 각 서비스 객체는 객체 생성의 의존성 책임을 지지 않게 한다.
개별 서비스 객체는 setter매서드나 생성자 인수를 제공하여 의존성을 주입할 수 있게 하며, DI컨테이너가 필요한 객체를 만들어 의존성을 주입한다.

확장
코드는 TDD, 리팩토링, 깨끗한 코드 등을 통해 확장하기 쉽게 유지할 수 있다.
시스템은 관심사를 적절히 분리해 점진적으로 발전할 수 있다.
과거 EJB는 관심사를 적절히 분리하지 못하고 강하게 결합된 탓에 확장이 어렵고 테스트도 어려웠다.
Cross-Cutting(횡단) 관심사 처리를 위한 프록시 방법을 직접 구현하면 제법 복잡해 지며, 스프링의 AOP와 같은 프레임워크로 추상화하여 사용할 필요가 있다. AspectJ 를 이용하는 방법도 있지만 80~90% 상황에서는 AOP로도 충분하다.

테스트 주도 시스템 아키텍처 구축
건축물을 지을 때는 BDUF(Big Design Up Front, 구현을 시작하기 전에 앞으로 벌어질 모든 사항을 설계)를 추구하지만, 소프트웨어는 단순하면서도 멋지게 분리된 아키텍처로 재빨리 출시 한 후, 기반 구조를 추가하며 조금씩 확장해 나가야 한다.
이를 위해, 각기 POJO 객체로 구현되는 모듈화된 관심사 영역(도메인)으로 구성하고, 서로 다른 영역은 최소한의 영향을 주도록 통합해야 한다.관심사를 모듈로 분리하여 기민함을 제공해야 한다. 표준을 사용하여 아이디어와 컴포넌트를 재사용하기 쉽게 유지해야 한다.

모든 추상화 단계에서 의도를 명확히 표현하고, 각 구현 관심사를 분리하여 관점에 따라 추상화해야 한다.

 

반응형