-
[독서] 클린 코더우아한 테크코스/테크코스 2020. 2. 24. 10:35반응형
자신의 시간
주 40시간을 일을 한다면, 그 외 추가로 20시간을 자신을 위해 사용해야 함
프로 소프트웨어 개발자라면 알아야하는 최소한의 기능 목록
디자인 패턴
24가지 GOF 패턴을 설명할 수 있고, POSA 패턴을 실무에 적용할 수준으로 알아야 함
설계 원칙
SOLID 객체지향 원칙을 알아야 하고 컴포넌트 개념을 충분히 이해해야 함
방법론
XP, 스크럼, 린, 칸반(KANBAN), 폭포수, 구조적 분석, 구조적 설계 개념을 충분히 이해해야 함
원칙
테스트 주도 개발(TDD), 객체지향 설계, 구조적 프로그래밍, 지속적 통합, 페어 프로그래밍을 실천해야 함
도구
UML, 데이터 흐름도(DFD), 구조 차트(Structure Chart), 페트리 넷(Petri Net), 상태 전이 다이어그램과 테이블(State Transition Diagram and Table), 흐름도(flow chart), 결정 테이블(decision table)을 어떻게 쓰는지 알아야 함
연습하기
도조(DOJO) = 도장
많은 프로그래머들이 코딩 연습을 무술 연마의 비유를 받아들였고, 코딩 도장(도조)의 이름으로 굳혀짐
카타(KATA) = 품새
코드 카타는 프로그래머가 연습과 반복을 통해 기술을 연마하도록 돕는 프로그래밍 연습
- 어떤 문제 풀이를 가상해 만든 단축키 사용과 마우스 조작을 정교하게 짜 모은 것
- 엄밀히 말하자면 문제 풀이에 포함된 동작들과 결정 내리기를 연습하는 것
단축키와 코드 관용구(idiom) 탐색을 익히거나, TDD나 지속적 통합(CI)를 익히는데도 좋지만 문제/해결 모음을 무의식 상태에 주입해 실제 프로그래밍에서 문제를 만났을 때 자연스럽게 해법을 알아내도록 만드는 좋은 방법
와사(WASAA) = 합맞추기
두 명이 짝을 이뤄 카타나 비슷한 문제를 고른 후 한 프로그래머가 단위 테스트를 만들면 다른 프로그래머가 그 테스트를 통과하는 코드를 짜고, 그 이후 역할을 바꿈
표준 카타를 골랐다면 풀이는 알기 때문에 연습과 더불어 상대의 키 사용, 마우스 동작, 카타를 얼마나 잘 외웠는지를 평가
상대가 새로운 문제를 골랐다면 테스트를 만드는 쪽의 프로그래머가 문제 해결 방법 및 제약 조건 설정에 에 더 많은 권한을 가지게 됨, 이는 상황을 재미있게 만듦 = 예) 정렬을 구현할 알고리즘을 골랐을 때, 짝이 문제를 풀 때 속도와 메모리 공간에 제약을 걺
란도리 = 대련
와사와 비슷한데, 두 명이 아닌 여러 명이 한다는 것이 다름
첫 사람이 테스트 코드를 짜고, 그 다음 사람이 구현 코드를 만들고 테스트 코드를 짜고, 그 다음 사람이 - 무한 반복
기타
좋은 코드는 불가능한가? 프로다운 일 처리는 불가능한가? - 아니요, 가능합니다.
위기에 처했을 때 훈련과 규율(disipline)을 따른다면 진정으로 그 규율을 믿는다는 뜻
약속(commitment)을 하는 행동
1. 하겠다고 말한다. / 2. 진심을 담는다 / 3. 실제로 실행한다.
모호한 단어는 사용하지 않고, 명확하고 자신이 할 수 있는 부분만 약속한다.
또한 그 약속 관련하여 일어날 부분도(불확실성 / 미래-체력방전 등) 미리 얘기해둔다.
코딩을 위한 준비된 자세
코딩은 강하게 집중해야만 한다. 지치거나 주의력이 흩어졌다면 코드를 만들지 말고, 정신을 집중할 방법을 찾아라.
1. 코드는 반드시 동작해야 한다.
- 풀고자 하는 문제가 어떤 문제며 어떻게 풀어야 하는지 확실히 이해해야 한다.
- 해결법을 나타낸 코드에 믿음이 가는지 확인해야 한다.
- 해결법의 언어, 플랫폼, 현재 아키텍처, 시스템의 모든 결점까지 구석구석 지속적으로 관리해야 한다.
2. 코드는 고객이 제시한 문제를 풀어야 한다.
- 가끔 알고보니 고객의 요구사항이 고객의 문제를 해결하는데 도움이 안되는 경우도 있지만, 이런 상황을 파악하고 고객과 협상해 고객의 진정한 필요를 충족시키는 일은 나에게 달렸다.
3. 코드는 기존 시스템에 잘 녹아들어야 한다.
- 기존 시스템의 경직성, 취약함, 불투명도를 높이면 안된다.
- 의존성 관리도 잘해야한다.
- 코드는 견고한(SOLID) 객체지향 원칙을 따라야 한다.
4. 코드는 다른 프로그래머가 읽기 쉬워야 한다.
- 주석을 잘 달라는 소리가 아니라, 만든 사람의 의도가 드러나도록 코드를 잘 다듬어야 한다는 뜻이다.
TDD
3가지 법칙
1. 실패한 단위 테스트를 만들기 전에는 제품 코드를 만들지 않는다.
2. 컴파일이 안 되거나 실패한 단위 테스트가 있으면 더 이상의 단위 테스트를 만들지 않는다.
3. 실패한 단위테스트를 통과하는 이상의 제품 코드는 만들지 않는다.
인수 테스트와 단위 테스트
인수 테스트
단위 테스트가 아님
사업부를 위해 사업부가 작성(개발자가 마무리할 수도)
사업적 관점에서 시스템이 어떻게 운영되어야 하는지를 구체적으로 표시한 공식 요구사항 문서
보는사람 : 사업부 및 프로그래머
단위 테스트
프로그래머가 프로그래머들을 위해 만듦
코드의 최하위 구조와 행동을 설명하는 공식 디자인 문서
인수 테스트와 단위 테스트의 병행
같은 사항을 테스트하는 것은 사실이지만, 불필요한 일이 아님
1. 같은 내용을 테스트하더라도, 다른 메커니즘과 경로를 통해 테스트
- 단위 테스트 : 특정 클래스의 메서드를 호출하면서 시스템 내부로 파고 듦
- 인수 테스트 : API나 때때로는 UI 수준으로 조금 더 원거리에서 시스템을 호출
- 고로 실행 경로는 매우 다름
2. 주 기능이 테스트가 아니기 때문
- 테스트란 사실은 부수적임
- 단위 테스트와 인수 테스트는 첫째가 문서고 둘째가 테스트임
- 테스트의 주 목적 : 시스템의 디자인, 구조 및 행동에 대한 공식적인 문서화
- 테스트가 자동으로 명세하는 디자인, 구조 및 행동을 검증한다는 사실도 몹시 쓸모가 있지만, 진정한 목적은 사양의 명세
테스트 자동화 피라미드
~5% - 탐색 테스트(Exploratory Tests) - 수동 ~10% - 시스템 테스트(System Tests) - GUI ~20% - 통합 테스트(Integration Tests) - API ~50% - 컴포넌트 테스트(Component Tests) - API ~100% - 단위 테스트(Unit Tests) - XUnit
단위 테스트(Unit Tests)
프로그래머에 의해, 프로그래머를 위해 시스템 프로그래밍 언어로 만든 테스트
시스템의 최하위 계층을 명세하려는 의도로 만듦
개발자들은 제품 코드를 만들기 전에 만들려는 제품 코드를 명세하려고 테스트 코드를 먼저 만듦(TDD)
- 테스트 코드는 지속적 통합의 일부로 실행되어 프로그래머가 의도한 바를 지켜냄
단위 테스트의 커버리지는 최대한 100%에 가까워야 함
- 보통 커버리지의 목표는 90~99%가 되어야 함
- 커버리지 : 진정한 커버리지를 뜻하며, 코드의 동작을 단언(assert)하지 않고 넘어가는 가짜 테스트와는 반대
컴포넌트 테스트(Component Tests)
인수 테스트의 일종
보통 컴포넌트 테스트의 대상은 시스템의 독립 컴포넌트이므로 컴포넌트 대상 테스트의 경우 해당 업무 규칙을 테스트하는 인수 테스트
시스템의 독립 컴포넌트 - 업무 규칙을 감싸고 있음
컴포넌트 테스트는 컴포넌트를 감싸고 있음, 컴포넌트에 입력 데이터를 넣고 출력 값을 받아 모음.
- 입력 값에 대해 출력 값이 올바른지 테스트
- 테스트 대상이 아닌 시스템 컴포넌트는 적절한 모의(mock) 컴포넌트와 테스트 대역(test-doubling) 기법으로 테스트로부터 분리
QA와 사업부는 개발팀의 도움을 받아 컴포넌트 테스트를 만듦
- FitNess, JBehave, Cucumber 같은 컴포넌트 테스트 개발 환경을 사용
- GUI 컴포넌트의 경우 Selenium이나 Watir 같은 GUI 테스트 환경으로 테스트함
= 사업부가 테스트를 직접 만들지 않는 경우에도 테스트를 읽고 이해해야 하기 때문
대략 시스템의 절반 정도를 감당함
행복한 경로(happy-path)쪽에 치우쳐있으며 모퉁이 조건, 경계 조건, 대체 경로(alternate-path)는 아주 명백한 경우에만 처리
불행한 경로(unhappy-path)는 대부분 단위 테스트로 처리하며 컴포넌트 테스트에서는 의미가 없음
통합 테스트(Integration Tests)
여러 컴포넌트로 이뤄진 큰 시스템에서만 의미가 있음
컴포넌트 묶음을 모아 묶음끼리 제대로 상호작용을 하는지 테스트
테스트 대상이 아닌 시스템의 다른 컴포넌트는 보통 적절한 모의(mock) 컴포넌트와 테스트 대역(test-double)으로 테스트와 분리
통합 테스트는 안무(choreography) 테스트
- 업무 규칙은 테스트하지 않고, 조립한 컴포넌트 묶음끼리 얼마나 잘 어우러져 춤을 추는지 테스트함
통합 테스트는 배관(plumbing) 테스트
- 컴포넌트끼리 서로 적절히 연결되어 또렷이 소통하는지 테스트
대개 시스템 아키텍트나 수석 설계자가 만듦
- 시스템 구조 설계가 튼튼하다는 사실을 보장
- 성능 테스트나 처리량(throughput) 테스트를 하기도 하는 단계
대개 컴포넌트 테스트에 썼던 언어와 환경으로 만듦
- 실행에 시간이 많이 들기 때문에 보통 지속적 통합때는 돌리지 않음
- 대신 주기적으로(매일 밤, 주 단위 등) 만든 이가 필요할 때마다 테스트를 돌ㄹ
시스템 테스트(System Tests)
통합한 시스템 전체를 대상으로 하는 자동화 테스트 = 궁극적인 통합 테스트
- 직접적으로 업무 규칙을 테스트하지는 않음
- 시스템이 올바르게 연결되었고, 각 부분이 계획에 따라 상호작용하는지 테스트
- 보통 성능이나 처리량(throughput) 테스트는 이 단계에서 진행
시스템 아키텍트나 기술 책임자가 만듦
- 대개 UI 통합 테스트에서 썼던 언어와 환경으로 만듦
- 실행 속도에 비해 비교적 자주 돌리는 편이지만, 자주 돌리면 더 좋음
대략 시스템의 10%를 감당함
- 시스템이 올바르게 동작하는지보다 시스템을 올바르게 빌드했는지를 확실히 하려는 목적이기 때문
- 기반 소스코드와 컴포넌트가 제대로 동작하는지는 피라미드의 하위 계층에서 이미 확인
수동 탐색 테스트(Exploratory Tests)
키보드에 손을 얹고 모니터를 직접 보며 하는 테스트
- 자동화된 테스트가 아니며 스크립트로 작성된 테스트도 아님
목적 : 시스템이 기대하는 대로 동작하는지 확인하는 동시에 예상치 못한 오류를 찾아내는 것
- 목표 달성에는 인간의 두뇌와 창의력으로 시스템을 검사하고 탐색하는 과정이 필요함
- 테스트 계획을 문서로 만드는 행동은 이런 테스트의 목표에 어긋남
목표는 커버리지가 아님
- 모든 업무 규칙과 실행 경로를 빠짐없이 검사할 생각은 없음
- 사용자의 조작과 시스템이 잘 동작하는지 확인하고 가능한 많은 특이사항을 창의적으로 발견해내는 일이 목표
PERT(Program Evaluation and Review Technique)
프로그램 평가와 검토 기술; 추정을 계산하는 방법을 포함
추정을 관리자에게 적합한 확률 분포로 바꾸는 아주 간단하지만 매우 효과적인 길을 제시
3방 분석(trivariate analysis) - 업무를 추정할 때 세 가지 숫자를 제시
- O(optimistic) : 낙관적 추정 값, 발생 확률은 1%에도 못미치는 모든 일이 완전히 잘 돌아갔을 때의 추정
- N(nominal) : 명목 추정 값, 성공 확률이 가장 큰 값
- P(pessimistic) : 비관적 추정 값, 모든 상황을 다 고려해야 함(대재앙 제외), 발생 확률은 1%에도 못미치지는 모든 상황을 다 고려한 것
3방 분석을 이용한 확률 분포
μ = (O + 4N + P) / 6
- μ(뮈/뮤)는 업무에 드는 예상시간, 대부분 업무에서 이 값은 비관적 값으로 치우치는데, 확률 분포의 최대 기간이쪽이 최소 기간쪽보다 길기 때문
σ = (P - O) / 6
- σ(시그마)는 업무에 대한 확률 분포의 표준 편차, 업무가 얼마나 불확실한지를 나타내는 값. 이 값이 크면 불확실함도 큼
업무 모음을 끝내는 데 걸리는 시간
- 업무별 μ 시간을 모두 합하면 됨
업무 모음의 표준 편차
- 업무별 σ를 제곱해서 더한 후 그 값의 제곱근
반응형'우아한 테크코스 > 테크코스' 카테고리의 다른 글
[Vim] Game - pacvim vs VIM Adventures (0) 2020.03.02 [독서] 코딩을 지탱하는 기술 (0) 2020.02.24 [Java] O/R 매핑 프레임워크로 데이터 액세스 레이어 구현 (0) 2020.02.23 [Java] JDBC / 데이터 액세스 레이어 / DAO (0) 2020.02.23 [VIM] Intellij에서 vim쓰기 (0) 2020.02.22