BOOKS
Pragmatic Programmer 실용주의 프로그래머
파란실버라이트
2018. 2. 9. 12:10
- ㄴ서문
- 프로그래밍은 기예(Craft)다. 컴퓨터에게 여러분이 시키고 싶은 일을 하게끔 난드는 것이다.
- 특정한 환경 조건의 집합마다 각 집합에 가장 적절한 시스템이 있을 뿐이다. 이것이 실용주의가 뜻하는 바다.
- 어떤 특정 기술에 메이면 안되며, 개별 상황마다 그 상황에서 좋은 해결방안을 고를 수 있도록 충분한 배경지식과 경험이 필요
- 배경지식 - 컴퓨터 과학의 기본 원리들을 이해하는 것
- 경험 - 다양한 프로젝트를 수행해보는 것
- 더 효율적이고 생산성 높은 프로그래머가 되고 싶어하는 사람들 대상
- 실용주의 철학
- 문제를 항상 더 큰 맥락에 놓으려 하고, 항상 더 큰 그림을 보려한다.
- 자신이 하는 모든 일에 책임을 진다.
- 소프트웨어 엔트로피
- '깨진창문'(나쁜 설계, 잘못된 결정, 형편없는 코드)을 고치지 않을 채로 내버려두지 마라, 발련하자마자 바로 고처라
- 고칠 시간이 충분하지 않다면 판자로 덮는 것만이라도 하라. 불쾌한 코드를 주석처리하거나, Not implemented라는 메시지 표시 , Dummy 데이타로 대치해 놓아라. 더 이상의 손상을 예방하기 위해 어떤 조치든취하고 현 상황을 잘 관리하고 있다는 것으 보이라
- 적당히 괜찮을 소프트웨어
- 완벽하게 훌륭한 프로그램을 과도하게 장식하거나 지나칠 정도로 다듬느라 망치지 말라. 그냥 넘어가고 코드가 현재 상태에서 한동안은 그대로 있도록 놓아두라. 완벽하지 않을 수도 있다. 걱정하지마라. 완벽해지기란 불가능하다.
- 지식 포트폴리오
- 주기적인 투자 / 공부
- 다각화 - 더 많은 기술에 익숙하다면 , 변화에 더 잘 적응
- 리스크 관리 - 여러분의 기술 달걀을 한 바구니에 모두 담지 마라
- 싸게 사서 비싸게 팔기 - 새롭게 떠오르는 기술을 학습
- 검토 및 재조정 - 인기 있는 기술 습득 or 낡은 기술 복습
- 실용주의 접근법
- 반복하지 마라 / 실용 주의 프로그래머의 가장 중요한 도구 중 하나
- 직교성 - 독립성(Independence) or decoupling
- 프로젝트 팀 구조 직교성 확인 - 요청된 개별 변화에 대한 토론에 참여할 필요가 있는 사람이 몇인가를 보라, 숫자가 클 수록 직교성은 낮다.
- 직교 적인 설계를 테스트 - 특정 기능에 대한 요구사항을 극적으로 변경했을 경우 몇 개의 모듈이 영향을 받는가?
- 단위 테스트를 만드는 것 자체가 직교성을 테스트
- 버그를 수정하고 테스트를 마친 뒤 버그 수정에 대한 테그를 붙여라. 각 버그 수정에 의해 영향 받는 소스 파일의 개수에 대한 월 단위 리포트를 받아볼 수 있다.
- 가역성
- 많은 사람들이 코드를 유연하게 유지하려고 노력한다. 하지만 아키텍처, 배포, 벤더 통합 영역의 유연성에 대해서고 관심 필요
- 벤더 의존적인 수행문들이 코드 전반에 흩어져 있을 것이고 , 이는 유지 보수성, 유연성을 극도로 떨어뜨리게 된다. 요구사항을 메타데이터에넣고, 필요한 수행문을 코드에 넣을 떄 AOP or Perl을 이요하여 메커니즘을 자동화 시켜라.
- 예광탄
- 프로토타입 - 나중에 버릴 수 있는 코드를 만든다.
- 예광탄 코드 - 기능은 별로 없지만 완견된 코드이면, 최종 시스템의 골격의 일부를 이룬다.
- 프로토타입을 예광탄이 하나라도 발사되기 전에 번저 일어나는 정찰과 정보 수집으로 생각
- 프로토 타입
- 프로토타입을 코드로 만들 때는 시작하기 전에 항상 모든 사람에게 여러분이 폐기처분할 코드를 작성하고 있다는 사실을 이해시켜야 한다.
- 도메인 언어
- 데이터 언어- 애플리케이션이 사용할 어떤 형식의 데이터 구조를 만든다. 환경설정 정보를 표현하기 위해 쓰이는 경우
- 명령형 언어 - 실제로 실행되며, 문자, 제어 구조체를 가진다.
- 도전? 한 프로젝트를 위해 개발한 프레임워크를 다른 프로젝트에서 재사용할 수 있는 방법들을 생각해 낼 수 있는가?
- 기본적인 도구
- 디버깅
- 버그를 목격하거나 혹은 버그 보고서를 보는 순간 첫 반응이 "그건 불가능"라면 여러분은 두말할 필요 없이 틀렸다.
- OS, 컴파일러, 혹은 써드파티 제품에 버그가 있을 수도 있다. 하지만 처음부터 그런생각을 하진 말라. 개발하고 있는 어플리케이션 코드에 버그가 존재할 가능성이 훨씬 더 크다.
- 실용주의 편집증
- 계약에 의한 설계 (Design by Contract , DBC)
- 선행조건 - 루틴이 호출되기 위해 참이어야 하는 것, 루틴의 요구사항
- 후행 조건 - 루틴이 자기갈 할 것이라고 보장하는 것, 루틴이 완료되었을 때 세상의 상태
- 클래스 불변식 - 호출자의 입장에서 이 조건이 언제나 참이라고 클래스가 보장
- 부끄럼 타는 , 게으른 ,Shy, Lazy code
- 시작하기 전에 자신이 수용할 것에 대해서 엄격하고
- 내어줄 것에 대해서는 최소한도를 약속
- 상속과 다향성에서 이런 계약이 빛을 발한다.
- 단정적 프로그래밍 (Assert)
- 두 가지 공공연한 잘못된 가정
- 테스트가 모든 버그를 발견한다
- 프로그램이 험한 세상에서 (로그파일이 하드를 full ) 도는 것을 잊는다.
- 첫째 방어선은 가능한 에러를 체크
- 놓친 것들을 잡아내기 위해 단정문을 쓰는 것이다.
- void writeString(char *string) { assert(string != NULL);
- 언제 예외를 사용할까?
- 예외가 프로그램의 정상 흐름의 일부로 사용되는 일은 거의 없어야 한다고 밑는다.
- 예외를 정상적인 처리과정의 일부로 사용하는 프로그램은 고전적인 스파게티 코드의 가독성 문제와 관리성 문제를 전부 떠안게 된다. 이런 프로그램은 캡슐화 역시 깨트린다. 예외처리를 통해 루틴과 그 호출자들 사이의 결합도가 높아져 버린다.
- 구부러지거나 부러지거나
- 유연함으 유지하는 한 가지 좋은 방법은 가능한 적은 양의 코드 작성
- 뷰에서 데이터 모델을 분리
- 모듈들이 데이터를 동기적, 비동기적으로 교환할 수 있는 만남의 장소 마련 => 칠판 Blackboard design pattern
- https://en.wikipedia.org/wiki/Blackboard_(design_pattern)
- 결합도 줄이기와 디미터 법칙
- 부끄럼 타는 코드를 작성 / 자신을 드러내지 말고, 많은 사람과 상호작용하지 말라.
- 디미터 법칙은 코드를 더 적응성 있고 강하게 만들어 주지만 '주계약자'로서 대가를 치러야 한다.
- 주계약자(Station Class)는 모든 하부 계약자(Order manager, part manager를 직접 관리하고 , 이들에게 위임해주어야한다.
- 실제로 이는 위임자에게 단순히 요청을 전달하는 역활만을 하는 간단한 위임 메서드를 상당수 만들어야 함을 의미
- 위임 메서드는 성능 저하, 메모리 과부하와 같은 문제 야기
- 메타프로그래밍
- 동적 설정 : 파일.ini
- 메타 데이터 주도 애플리케이션 (Java Hibernate framework?)
- 가능한 마지막 순간까지 세부 정의를 피하고, 세부사항을 소프트하게 , 변화하기 쉽게 남겨두라
- 언제 설정 정보를 읽어야 할까? 프로그램이 시작 될때?
- 실행되는 동안 메타데이터를 리로딩하고 적용할 수 있는 방법을 제공하는 것이 옳다.
- 동시성을 고려한 설계
- 더 깔끔한 인터페이스를 설계하는 방향으로 이끌기도 한다.
- 모듈(잘 정의된 단 하나의 책임만 가지는 것) 프로그래밍
- 런타임에 객체들이 어떻게 서로 이야기하게 만들어야 하나?
- 모듈 사이의 논리적 의존성은 어떻게 관리해야 하나?
- 즉 다른 객체들의 상태변화(갱신된 값)을 어떻게 동기화?
- 유연하고 깔끔한 방식으로 이루어져야 한다. 우리는 객체가 서로에 대해 너무 많이 알기를 원하지 않는다. 자기가 보고 싶은 것만 보도록 만들고 싶다. => 이벤트라는 개념에서 시작.
- 출판/구독
- 코딩하는 동안 해야할 일들
- 우연에 맡기는 프로그래밍, 행운과 어쩌다 오는 성곡에 의족하는 프로그래밍을 하지 말하야 한다. 대신 의도적 프로그래밍을 해야한다.
- 언제나 자기가 지금 무엇을 하고 있는지 알아야한다.
- 맹목적으로 코딩하지 마라. 완전하게 이해하지 못한 애플리케이션을 빌드하려 하거나, 익숙하지 않은 기술을 사용하려고 시도하지 마라 => 그런데 새로운 프로젝트는 해야한다. ^^;
- 계획을 세우고 그것을 바탕으로 진행하라 => 칸반 툴을 사용
- 신뢰할 수 있는 것에만 기대라=> 테스팅
- 여러분의 가정을 문서로 남겨라 => 사용자와 소통
- 코드 뿐만 아니라 가정도 테스트 해야한다.
- 노력을 기울일 대상의 우선순위를 정하라
- 과거의 노예가 되지 마라/ 기존 코드가 앞으로 짤 코드를 지배하도록 놓지 말라. 적절하지 않으면 어떤 코드도 교체 가능
- 단 일정이 늦어져 발생하는 비용이 필요한 변화를 만들지 않을 경우의 비용보다 적어야 한다.
- 리펙토링
- 리펙터링과 새로운 기능 추가를 동시에 하지 말라
- 리펙터링을 시작하기 전 든든한 테스트 집합이 있는지 먼저 확인
- 단계를 나누어서 신중하게 작업 / 작은 단위에서 큰단위로
- 계약을 잘 지키는지 테스트해보기
- 어떤 단위가 자기가 맺는 계약을 존중하는지 확실하게 보여주는 테스트 케이스를 작성
- 코드가 계약을 지키는지 확인
- 코드로 표현된 계약의 의미가 우리가 생각한 것과 일치하는지.
- 프로젝트 전에
- 실용주의 프로젝트
- 자동화 - Testing , CI, CD - 이런 환경에서 구축해야 한다.
- 가차 없는 데스트