시스템

문지은·2021년 10월 13일
0

clean code

목록 보기
9/10

시스템 제작과 시스템 사용을 분리하라

제작사용은 매우 다르다. 소프트웨어 시스템에서는 준비 과정런타임 로직을 분리해야 한다.
즉 시작 단계라는 관심사를 분리해야 한다. 아래의 코드는 시작 단계를 분리하지 않고 구현한 예시이다.

// lazy initialization / lazy evalutation
public Service getService() {
    if (service == null)
    	service = new MyServiceImpl(...)
    return service;
}

문제점들은 다음과 같다.

  1. getService 가 MyServiceImpl과 생성자 인수에 명시적으로 의존 -> 런타임에서 MyServiceImpl을 사용하지 않아도 의존성 해결하지 않으면 실행 불가

  2. 테스트할 때 테스트 전용 객체를 할당해야 한다.

  3. 런타임 로직과 객체 생성 로직 섞임 -> 테스트할 때 모든 실행 경로를 테스트 해야 한다.

  4. MyServiceImpl이 불필요하게 클래스 전체에 대한 맥락을 알고 있다.

이를 해결하기 위한 방법은 Main 분리, 팩토리가 있다.

Main 분리

생성과 관련된 코드는 모두 main 혹은 main이 호출하는 모듈로 옮기기

팩토리

애플리케이션이 객체가 생성되는 시점을 결정
IoC 기법을 의존성 관리에 적용한 메커니즘인 DI 활용 -> 새로운 객체는 넘겨받은 객체에 대한 책임만 맡으므로 SRP 법칙 만족

// 호출하는 객체가 반환되는 객체의 유형 제어하지 않음
MyService myService = (MyService)(jndiContext.lookup("NameOfMyService"));

여기서도 lazy initialization 사용이 가능하다.

확장

소프트웨어 시스템은 관심사를 적절히 분리해 관리한다면 점진적으로 발전할 수 있다. 여기 저기 흩어져 있던 관심사를 모듈화하고 캡슐화하는 방식으로 영속성을 얻을 수 있다. 여기서 횡단 관심사 라는 말이 나오게 된다.
자바에서 사용하는 관점 혹은 관점과 유사한 메커니즘은 자바 프록시, 순수 자바 AOP 프레임워크, AspectJ 관점이 있다.

자바 프록시

단순한 상황에 적합.

public class BankImpl implements Bank {
    private List<Account> accounts;
    ...
    // getter, setter 가지고 있는 POJO
    // 비즈니스 논리는 POJO로 구현
}

public class BankProxyHandler implements InvocationHandler {
    private Bank bank;
    ...
    // invoke 함수와 세부사항 코드
}

// 프록시에 핸들러를 넘겨 주어서 bank 메서드 구현
Bank bank = (Bank) Proxy.newProxyInstance(
    Bank.class.getClassLoader(),
    new Class[] {Bank.class},
    new BankProxyHandler(new BankImpl()));

프록시를 사용하면

  1. 깨끗한 코드를 작성하기 어렵고
  2. 실행 지점을 명시할 수 없다.

순수 자바 AOP 프레임워크

자바 프레임워크를 이용해서 보다 쉽게 프록시 구현이 가능하다.
비즈니스 논리는 POJO로 구현하고 이는 다른 도메인에 의존하지 않으므로 테스트 및 유지, 보수가 편하다.
스프링 설정 파일에서 bean을 설정하여 JDBC -> DAO -> 도메인 객체로 프록시 되도록 한다.

// 빈 설정 파일 적용
XmlBeanFactory bf = new XmlBeanFactory(new ClassPathResource("app.xml", getClass()));

// bank 도메인에 직접 접근하는 것 같지만 사실 JDBC에 접근
Bank bank = (Bank) bf.getBean("bank");

EJB3를 통해서 더 간편하게 표현 가능하다.

AspectJ

Spring AOP보다 더 빠르며 다양한 기능을 지원한다.
관심사를 관점으로 분리하는 가장 강력한 도구

정리

  • 관심사를 POJO로 구현하여 나누자.
  • 다른 영역은 유사한 도구를 통해 통합하자.
  • TDD를 적용하자.
  • 의사 결정을 최대한 미루자.(lazy initialization)
  • DSL을 활용하자.
profile
백엔드 개발자입니다.

0개의 댓글