[클린코드] Ch 11-12

Ericamoyed·2021년 2월 12일
1

클린코드

목록 보기
5/8

Ch 11. 시스템

시스템 수준에서도 깨끗함을 유지하는 방법

  • 애플리케이션 객체를 제작하고 의존성을 서로 "연결"하는 준비과정과, 준비 과정 이후에 이어지는 런타임 로직을 분리해야한다.
    • 그런데 내가 느끼기로는, 요새는 개발자가 따로 신경써서 분리하기 보다도 스프링 등의 프레임워크를 사용하면, 빈 생성이나 DI 과정들을 런타임 이전에 해주고, 런타임에서는 이미 생성된 빈들 기반으로 수행시키는 방식으로 자동으로 구성해주는 듯 ㅎ
  • Main 분리
    • 생성과 관련한 코드는 모두 main이나 main이 호출하는 모듈로 옮기고, 나머지 시스템은 모든 객체가 생성되었고 모든 의존성이 연결되었다고 가정하고 작성
  • 팩토리
    • 객체가 생성되는 시점을 애플리케이션이 결정해야할 경우도 있다.
    • 해당 경우에는 abstract factory 패턴을 사용하도록 한다.
      • 객체를 생성하는 시점은 애플리케이션이 결정하나, 객체를 생성하는 방식에 대한 코드는 애플리케이션이 모르게된다.
      • abstract factory 패턴은 간단히 아래의 그림으로 설명이 가능할 듯 하다.

        (출처: https://gmlwjd9405.github.io/2018/08/08/abstract-factory-pattern.html)
      • 상단의 출처에서 해당 그림 아래 부분 설명들을 더 보면 이해가 쉬울 것이다. 간단히 설명하자면 팩토리를 위한 팩토리를 만들어서 객체의 생성을 보다 더 쉽게 관리하기 위한 방식 정도.
  • 의존성 주입 (Dependency Injection)
    • 사용과 제작을 분리
    • 제어 역전 (Inversion of Control)을 의존성 관리에 적용한 메커니즘
    • 의존성 관리 맥락에서 객체는 의존성 자체를 인스턴스로 만드는 책임은 지지 않고, 이런 책임을 다른 '전담' 메커니즘, 스프링으로 얘기하자면 스프링 컨테이너에 넘긴다.
    • 클래스는 완전히 수동적이며, 의존성을 주입하는 방법으로 setter 메서드나 생성자 메서드를 제공한다. DI 컨테이너는 필요한 객체의 인스턴스를 만든 후, 제공한 메서드들을 통해 의존성을 설정함.
    • 실제로 생성되는 객체 유형은 설정 파일에서 지정하거나 특수 생성 모듈에서 코드로 명시 (ex. spring에서 xml이나 annotation으로 적용하는 것처럼..)
    • 대다수 스프링의 자바 DI 컨테이너는 필요할 때까지는 객체를 생성하지 않고, 대부분은 초기화 지연 등의 비슷한 최적화에 쓸 수 있도록 팩토리 호출/ 또는 프록시 생성 등을 제공한다.
  • 애자일 방식의 핵심: 오늘은 오늘 스토리에 맞춰 시스템을 구현하고, 내일은 새로운 스토리에 맞춰 시스템을 조정하고 확장하자! 깨끗한 코드라면 가능한 플로우
  • EJB 아키텍처 등에 대해 나오는데.. 최근에도 사용되는 기술들인지 공부 필요. 현재도 java에서 택하고 있는 아키텍처라면 이후에 이펙티브 자바 공부하면서 정리해두려고 함. 간단히만 다루겠음
    • 객체와 관계형 자료가 매핑되는 방식, 원하는 트랜잭션 동작 방식, 보안 제약 조건 등은 소스코드가 아닌 XML 배포 기술자에 작성한다.
      • 이는 AOP를 예견했다고 보임
      • 결국 cross-cutting(횡단 관심사)를 코드로부터 분리한다는 점에서 유사함
      • AOP 프레임워크는 대상 코드에 영향을 미치지 않는 상태로 동작 방식을 변경!
      • 빈은 다른 빈을 상속받지 못하고, DTO는 메서드가 없는, 앞에서 이야기 했던 자료 구조체 이다.
  • 자바 프록시
    • 프록시도 결국 디자인 패턴인 것을..

      (출처: https://m.blog.naver.com/gracefulife/220650929598)
    • JDK에서는 인터페이스에 대해서만 프록시를 지원
    • 프록시로 감쌀 인터페이스와, 비즈니스 논리를 구현하는 POJO(그냥 일반적인 자바 클래스를 의미)
    • Handler에서는 제네릭스 메서드를 자바 리플렉션 API를 통해 인터페이스 메서드로 매핑하는 역할을 하게 된다.
    • 자바 리플렉션 API

      (출처: https://brunch.co.kr/@kd4/8)
    • 간단히 얘기하자면, 실제 Class type을 알지 못해도 컴파일된 바이트코드를 기반으로 해당 Class에서 정의한 메소드, 변수들을 사용할 수 있게 하는 API를 의미한다. 그만큼 성능은 좋지 못한, 하지만 쓸모는 많은, 그런 친구.
    • 프록시를 사용하면 깨끗한 코드 작성은 어렵긴 하다.. 바이트 조작 라이브러리 등 코드 양과 크기가 방대해지기 때문..
    • 하지만 대부분의 프록시 코드는 판박이라서, 스프링 AOP 등의 도구로 자동화되었다. (AOP도 내부적으로 프록시를 사용하는 형태!)
    • 프로그래머는 설정 파일(XML)과 API를 사용해서 애플리케이션을 구축
    • 클라이언트는 Bank 객체에서 메소드를 호출하는걸로 알지만, 실제로는 Bank POJO의 동작을 확장한 decorator 객체 집합의 가장 외곽인, AppDataSource와 통신하게 되는 것.
    • XML은 장확하고 읽기 어렵다고는 하지만, 생성 방식이 은닉되어 있는 프록시 방식보다는 훨씬 명시적이여서, 스프링 프레임워크의 이러한 특징은 EJB 버전 3을 완전히 뜯어 고쳐, XML 설정 파이록 애너테이션 기능을 활용하여 횡단 관심사를 선언적으로 지원하는 스프링 모델을 따르게 되었다.
      • 모든 정보가 애너테이션 속에 있어 코드가 깔끔/깨끗하며
      • 애너테이션의 영속성 정보는 필요 시에 XML에 명시도 가능하다.

결론

  • 관점과 같은 메커니즘을 사용해, 각 구현 관심사를 분리하라.

Ch 12. 창발성

  • 깔끔한 코드 구현을 위한 네가지 규칙
    • 모든 테스트를 실행하라
    • 중복을 없애라
    • 프로그래머 의도를 표현하라
    • 클래스/메서드 수를 최소로 줄여라
    • 매번 하던 동일한 이야기.. 귀에 딱지 얹혀요
  • DIP와 같은 원칙을 적용하고 (추상 클래스/인터페이스에 의존하라는 원칙), DI(의존성 주입), 인터페이스, 추상화 등과 같은 도구를 활용하여 결합도를 낮춰라.
  • 고차원 중복을 제거하기 위해 template method 패턴을 애용해라. (부모 클래스로 추상화하고 자식 클래스에서 오버라이딩하여 중복을 줄이는 패턴)

후기

  • 분량 자체는 많지 않았으나, 공부해야할 부분이 많았던 챕터인 Ch 11. 그리고 매번 하던말의 단순한 중복이었던 Ch 12. 얼른 클코 스터디를 끝내고 이펙티브 자바를 읽어야 한다는 생각이 머릿 속을 채우는 시간이었다.
profile
꿈많은 개발자, 일상 기록을 곁들인

0개의 댓글