Community

개발자 99% 커뮤니티에서 수다 떨어요!

← Go back
[TIL] 8장. 경계, 9장.단위 테스트
#clean_code
2년 전
587

오늘 TIL 3줄 요약

  • 외부 코드의 깔끔한 통합과 외부 API와 가급적 독립적 구조.

  • API 설계가 분명치 않을 시, 자체적 인터페이스의 정의와 구현으로 통제.

  • Test-driven development는 코드에 대한 통제 확보.

TIL (Today I Learned) 날짜

2022.03.06

오늘 읽은 범위

8장.경계, 9장.단위 테스트

책에서 기억하고 싶은 내용을 써보세요.

  • 시스템에 들어가는 모든 소프트웨어를 직접 개발하는 경우는 드물다. 때로는 패키지를 사고, 때로는 오픈 소스를 이용한다. 떄로는 사내 다른 팀이 제공하는 컴포넌트를 사용한다. 어떤 식으로든 이 외부 코드를 우리 코드에 깔끔하게 통합 해야만 한다. 소프트웨어 경계를 깔끔하게 처리하는 기법과 기교. (144 p)

  • 외부 코드 사용하기 ~경계 인터페이스인 Map을 Sensors 안으로 숨긴다. 따라서 Map 인터페이스가 변하더라도 나머지 프로그램에는 영향을 미치지 않는다. Sensor 클래스 안에서 객체 유형을 관리하고 변환하기 때문이다. Sensors 클래스는 프로그램에 필요한 인터페이스만 제공한다. 그래서 코드는 이해하기 쉽지만 오용하기는 어렵다. Sensors 클래스는 (나머지 프로그램이) 설계 규칙과 비즈니스 규칙을 따르도록 강제할 수 있다. ~ (146 p)

  • 경계 살피고 익히기 ~외부 코드를 사용하면 적은 시간에 더 많은 기능을 출시하기 쉬워진다. ~외부 코드를 익히기는 어렵다. 외부 코드를 통합하기도 어렵다. (147 p)

  • log4j 익히기 ~지금까지 간단한 콘솔 로거를 초기화하는 방법을 익혔으니, 이제 모든 지식을 돋자적인 로거 클래스로 캡슐화한다. (149 p)

  • 학습 테스트는 공짜 이상이다 ~학습 테스트를 이용한 학습이 필요하든 그렇지 않든, 실제 코드와 동일한 방식으로 인터페이스를 사용하는 테스트 케이스가 필요하다. 이런 경계 테스트가 있다면 패키지의 새 버전으로 이전하기 쉬워진다. 그렇지 않다면 낡은 버전을 필요 이상으로 오랫동안 사용하려는 유혹에 빠지기 쉽다. (150 p)

  • 이직 존재하지 않는 코드 사용하기 ~아는 코드와 모르는 코드를 분리하는 경계다. ~경계 너머는 무지라는 안개와 구름으로 인해 한치 앞도 내다보기 어려웠지만, 점차로 우리에게 필요한 경계 인터페이스가 무엇인지 알게 되었다. ~저쪽 팀이 아직 API를 설계하지 않았으므로 구체적인 방법을 몰랐다. 그래서 우리는 구현을 나중으로 미뤘다. (150 p)

    우리는 (우리가 통제하지 못하며 정의되지도 않은) 송신기 API에서 CommunicationsController를 분리했다. 우리에게 필요한 인터페이스를 정의했으므로 CommunicationController 코드는 깔끔하고 깨끗했다. (151 p)

  • 깨끗한 경계 ~소프트웨어 설계가 우수하다면 변경하는데 많은 투자와 재작업이 필요하지 않다. 통제하지 못하는 코드를 사용할 때는 너무 많은 투자를 하거나 향후 변경 비용이 지나치게 커지지 않도록 각별히 주의해야 한다. 경계에 위치하는 코드는 깔끔히 분리한다. 또한 기대치를 정의하는 테스트 케이스도 작성한다. ~통제가 불가능한 외부 패키지에 의존하는 대신 통제가 가능한 우리 코드에 의존하는 편이 훨씬 좋다. 자칫하면 오히려 외부 코드에 휘둘리고 만다. 외부 패키지를 호출하는 코드를 가능한 줄여 경계를 관리하자. ~경계 인터페이스를 사용하는 일관성도 높아지며, 외부 패키지가 변했을 때 변경할 코드도 줄어든다. (152 p)

  • 표준 타이밍 함수를 호출하는 대신 운영체제에서 코드를 분리했으리라. 타이밍 함수를 직접 구현해 시간을 완전히 통제했으리라 ~테스트 케이스를 모두 구현하고 통과한 후에는 내 코드를 사용할 사람들에게도 공개했으리라. 테스트 코드와 내 코드를 같은 소스 패키지로 확실하게 묶어 체크인했으리라. ~앞으로 눈부신 성장을 이웠지만 앞으로 갈 길은 여전히 멀다. ~제대로 된 테스트 케이스를 작성해야 한다. (155 p)

  • TDD 법칙 세가지 ~실제 코드를 짜기 전에 단위 테스트부터 짜라고 요구한다 ~첫째 법칙: 실패하는 단위 테스트를 작성할 때까지 실제 코드를 작성하지 않는다. 둘째 법칙: 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다. 셋째 법칙: 현재 실패하는 테스트를 통과할 정도러만 실제 코드를 작성한다. (155 p)

  • 깨끗한 테스트 코드 유지하기 ~지저분한 테스트 코드를 내놓으나 테스트를 안 하나 오십보 배보라는, 아니 오히려 더 못하다는 사실 ~실제 코드가 진화하면 테스트 코드도 변해야 한다. ~테스트 슈트가 없으면 개발자는 자신이 수정한 코드가 제대로 도는지 확인할 방법이 없다. ~시스템 이쪽을 수정해도 저쪽이 안전하다는 사실을 검증하지 못한다. ~의도하지 않은 결함 수가 많아지면 개발자는 변경을 주저한다. 변경하면 득보다 해가 크다 생각해 더 이상 코드를 정리하지 않는다. 그러면 코드가 망가지기 시작한다. (156 p)

  • 테스트는 유연성, 유지보수성, 재사용성을 제공한다 ~테스트 코드를 깨끗하게 유지하지 않으면 결국은 잃어버린다. 그리고 테스트 케이스가 없으면 실제 코드를 유연하게 만드는 버팀목도 사라진다. 코드에 유연성, 유지보수성, 재사용성을 제공하는 버팀목이 바로 단위 테스트다. 테스트 케이스가 없다면 모든 변경이 잡정인 버그다. 아키텍처가 아무리 유연하더라도, 설계를 아무리 잘 나눴더라도, 테스트 케이스가 없다면 개발자는 변경을 주저한다. 버그가 숨어들까 두렵기 떄문이다. ~실제 코드를 점검하는 자동화된 테스트 슈트는 설계와 아키텍처를 최대한 깨끗하게 보존하는 열쇠다. (157 p)

    ~깨끗한 테스트 코드 ~가독성 ~명료성, 단순성, 풍부한 표현력 ~최소의 표현으로 많은 것을 나타내야 한다. (158 p)

    ~코드를 읽는 사람은 온갖 잡다하고 세세한 코드에 주눅들고 헷갈릴 필요 없이 코드가 수행하는 기능을 재빨리 이해한다. (161 p)

  • 도메인에 특화된 테스트 언어 ~API 위에다 함수와 유틸리티를 구현한 후 그 함수와 유틸리티를 사용함으로 테스트 코드를 짜기도 읽기도 쉬워진다. ~이런 테스트 API는 처음부터 설계된 API가 아니다. 잡다하고 세세한 사항으로 범벅된 코드를 계속 리펙터링하다가 진화된 API다. ~숙련된 개발자라면 자기 코드를 좀 더 간결하고 표현력이 풍부한 코드로 리펙터링해야 마땅하다. ~실제 코드만큼 효율적일 필요는 없다. ~실제 환경과 테스트 환경은 요구사항이 판이하게 다르다. ~단지 시스템 최종 상태가 온도가 '급강하'했는지 그것만 산경 써서 살펴보기 바란다. ~가독성 ~tic 함수는 wayTooCold라는 함수를 만들어 숨겼다. (163 p)

  • F.I.R.S.T ~빠르게, 독립적으로, 반복가능하게, 자가검증하는, 적시에 ~테스트가 느리면 자주 돌릴 엄두를 못낸다. 자주 돌리지 않으면 초반에 문제를 찾아내 고치지 못한다. ~각 테스트는 서로 의존하면 안 된다. ~각 테스트는 독립적으로 그리고 어던 순서로 실행해도 괜찮아야 한다. 테스트가 서로에게 의존하면 하나가 실패할 떄 나머지도 잇따라 실패하므로 워인을 진단하기 어려워지며 후반 테스트가 찾아야 할 결함이 숨겨진다. (167 p)

오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요

  • Calculation Manger를 사용해서 외환 플로우 계산, 외환 환산 조정 계산, 주주 지분 계산 등 다차원 비즈니스 규칙 만들보고 싶어졌다.

궁금한 내용이 있거나, 잘 이해되지 않는 내용이 있다면 적어보세요.

  • 제네릭스(Generics):

    1. Generics add stability to your code by making more of your bugs detectable at compile time. on Oracle Javadocs

    2. 제네릭은 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법을 의미한다. on 생활코딩

    3. 지네릭스는 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입체크를 해주는 기능이다. on 자바의 정석

    *[출처_https://yaboong.github.io/java/2019/01/19/java-generics-1/]

  • 비즈니스 규칙: Calculation Manager를 사용하면 복잡한 다차원 비즈니스 규칙을 생성, 검증, 배포 및 관리할 수 있습니다.

    일바적으로 다음 작업을 위해 비즈니스 규칙을 생성합니다.

    엔티티 간에 비용 할당, 수익 모델링, 비용 모델링, 대차대조표 준비, 현금 플로우 계산, 외화 환산 조정 계산, 그룹 및 소액 주주 지분 계산, 이연 법인세 계산 등.

    비즈니스 규칙을 생성하려면 데이터베이스 아웃라인 및 작업 중인 애플리케이션에 대해 잘 알고 있어야 합니다. 이러한 정보가 있으면 비즈니스 규칙을 보다 효율적으로 생성할 수 있습니다. 또한 데이터에 대해 다음 내용을 알고 있어야 합니다.

    데이터가 저장되고 집계되는 방법

    데이터가 데이터베이스에 로드된 레벨

    계산 순서

    계산 수행에서의 주요 가정

    ~

    *[출처_*https://docs.oracle.com/cloud/help/ko/epm-common/ECALC/about_business_rules.htm#ECALC-cmgr_rules_18]

오늘 읽은 다른사람의 TIL

  • 00님의 TIL (url 링크)