It's just like pok    version4


실용주의 프로그래머

 | 

숙련공을 마스터로 - 실용주의 프로그래머를 만드는 몇가지 조언들

- [실용주의 철학](#1) - 고양이가 내 소스코드를 삼켰어요 - 소프트웨어 엔트로피 - 돌멩이 수프와 삶은 개구리 - 적당히 괜찮은 소프트웨어 - 지식 포트폴리오 - 소통하라! - [실용주의 접근법](#2) - 중복의 해악 - 직교성 - 가역성 - 예광탄 - 프로토타입과 포스트잇 - 도메인 언어 - 추정 - [기본적인 도구](#3) - 일반 텍스트의 힘 - 조개놀이(Shell Games) - 파워 에디팅 - 소스코드 관리 - 디버깅 - 텍스트 처리 - 코드 생성기 - [실용주의 편집증](#4) - 계약에 의한 설계 - 죽은 프로그램은 거짓말을 하지 않는다 - 단정적 프로그래밍 - 언제 예외를 사용할까 - 리소스 사용의 균형 - [구부러지거나 부러지거나](#5) - 결합도 줄이기와 디미터 법칙 - 메타 프로그래밍 - 시간적 결합 - 단지 뷰일 뿐이야 - 칠판 - [코딩하는 동안 해야 할 일들](#6) - 우연에 맡기는 프로그래밍 - 알고리즘의 속도 - 리팩터링 - 테스트하기 쉬운 코드 - 사악한 마법사 - [프로젝트 전에](#7) - 요구사항의 구렁텅이 - 불가능한 퍼즐 풀기 - 준비가 되어야만 - 명세의 함정 - 동그라미와 화살표 - [실용주의 프로젝트](#8) - 실용주의 팀 - 유비쿼터스 자동화 - 가차 없는 테스트 - 결국은 모두 글쓰기 - 위대한 유산 - 오만과 편견

실용주의 철학

고양이가 내 소스코드를 삼켰어요

일을 책임있게 할것을 강조. 나쁜 상황에 대해 어설픈 변명을 생각하기보다 원인과 대안을 생각해보는 것이 훨씬 실용적이다. 상황개선을 위해 한박자 쉬어가며 냉정히 생각하는것도 좋은 방법. 고양이가 소스를 삼켰다고 할순 없지 않은가?

  • 프로토타입과 포스트잇
  • 리팩터링
  • 테스트하기 쉬운 코드
  • 유비쿼터스 자동화
  • 가차 없는 테스트

소프트웨어 엔트로피

깨진 창문 효과(창문이 하나 깨진것 뿐인데 나중에는 폐허가 되는 현상)- 깨진 창문을 내버려 두지 말것.

  • 돌멩이 수프와 삶은 개구리
  • 리팩터링
  • 실용주의 팀

돌멩이 수프와 삶은 개구리

돌멩이로 만든다는 수프덕분에 모두가 맛있게 먹은 수프가 된 경우. 시작피로(start-up fatigue)와 그 해결책인 ‘돌멩이’를 내노을것. 그 반대로, 개구리는 탕속에서 서서히 익어죽는다.

  • 소프트웨어 엔트로피
  • 우연에 맡기는 프로그래밍
  • 리팩터링
  • 요구사항의 구렁텅히
  • 실용주의 팀

적당히 괜찮은 소프트웨어

우리는 종종 뭔가 나아지게 하려다가 괜찮은 것마저 망친다(리어왕 中). 타협과정과 언제 멈추어야 할지를 아는것은 중요한 일이다.

  • 예광탄
  • 요구사항의 구렁텅이
  • 실용주의 팀
  • 위대한 유산

지식 포트폴리오

지식에 투자하고 지식포트폴리오를 만들어라.

  주기적인 투자
  다각화
  리스크 관리
  싸게 사서 비싸게 팔기
  검토 및 재조정
 

소통하라!

청중을 알아라 - 말하고 싶은게 무언지 알고 직접 청자가 되어라.

  • 프로토타입과 포스트잇
  • 실용주의 팀

실용주의 접근법

중복의 해악

DRY - Dont Repeat Yourself. 만일 중복되어 있는것이 있다면, 그것이 잘못되어 수정할때 다른 잘못된곳을 기억하고 있어야한다는 것을 뜻한다. (리팩토링에서 산탄총 수술)

  • 직교성
  • 텍스트 처리
  • 코드 생성기
  • 리팩터링
  • 실용주의 팀
  • 유비쿼터스 자동화
  • 결국은 모두 글쓰기

직교성

관련 없는 것들 간에 서로 영향이 없도록 하라. 리팩터링에서 확산적 변경. 모듈라나 컴포넌트, MVC 아키텍쳐, 레이어등… ‘특정 기능에 대한 요구사항을 극적으로 변경했을 경우, 몇 개의 모듈이 영향을 받는가?’등으로 직교적인 설계를 테스트 해 볼수 있다.

  • 중복의 해악
  • 소스코드 관리
  • 계약에 의한 설계
  • 결합도 줄이기와 디미터 법칙
  • 메타프로그래밍
  • 단지 뷰일 뿐이야
  • 리팩터링
  • 테스트하기 쉬운 코드
  • 사악한 마법사
  • 실용주의 팀
  • 결국은 모두 글쓰기

가역성

최종 결정이란 없다. 유연한 아키텍처를 만들어라.

  • 결합도 줄이기와 디미터 법칙
  • 메타프로그래밍
  • 단지 뷰일 뿐이야

예광탄

어둠속에서 빛을 발하는 코드. 스캐폴딩의 프로토타입 코드와 최종프로그램속에서의 예광탄코드

  • 적당히 괜찮은 스프트웨어
  • 프로토타입과 포스트잇
  • 명세의 함정
  • 위대한 유산

프로토타입과 포스트잇

프로토타입 - 스캐폴딩 - 으로 적당한 것들

  아키텍처
  기존 시스템에 추가할 새로운 기능
  외부 데이터의 구조 혹은 내용
  써드파티 도구나 컴포넌트
  성능문제
  사용자 인터페이스 설계
  
  • 고양이가 내 소스코드를 삼켰어요
  • 소통하라!
  • 예광탄
  • 위대한 유산

도메인 언어

문제 도메인에 가까운 언어를 통한 프로그래밍. 연습장에서의 낙서설계?

  • 메타프로그래밍

추정

추정을 통한 프로젝트의 성공적 관리. 단계반복의 점증적 개발

  무엇을 묻고 있는지 - 요구사항
  시스템 모델
  모델의 컴포넌트와 상호작용
  컴포넌트의 매개변수 찾기와 매개변수 값
  추정치를 기록하는 용기
 
  • 알고리즘의 속도

기본적인 도구

일반 텍스트의 힘

최소 공통분모로써의 텍스트

  구식이 되는 것에 대한 보험
  호환성
  더 쉬운 테스트
 
  • 소스코드 관리
  • 코드 생성기
  • 메타프로그래밍
  • 칠판
  • 유비쿼터스 자동화
  • 결국은 모두 글쓰기

조개놀이(Shell Games)

명령어 쉘의 힘. 명령어를 쉽게 다룰수 있는 스크립트언어 한개쯤을 내 수족으로…

  • 유비쿼터스 자동화

파워 에디팅

잘 사용할 수 있는 에디터를 가져라. 나의 경우에는 vim, 반면에 나는 통합환경도 좋아한다.

소스코드 관리

언제나 소스코드 관리 시스템을 사용하기. 회사의 소스코드관리 시스템은 훌륭하다. CVS보다 SVN이 좋아보인다.

디버깅

버그를 재현하고 데이터를 가시화하며 트레이싱하고 가정하지말것이며, 증명하라. 젠장. 버그를 개발의 연장이라 생각하자. 다른곳에서 본 멋진 말 한마디. 코드작성은 백지를 디버깅하는 과정이다.

  • 단정적인(assertive) 프로그래밍
  • 우연에 맡기는 프로그래밍
  • 유비쿼터스 자동화
  • 가차 없는 테스트

텍스트 처리

텍스트 처리 언어를 하나 익혀라. 익히고 싶다. 특히 awk 와 PHP, perl ei 모드..

  • 중복의 해악

코드 생성기

코드를 작성하는 코드를 만들어라는 말. 자동화의 중요성

  • 중복의 해악
  • 일반 텍스트의 힘
  • 사악한 마법사
  • 유비쿼터스 자동화

실용주의 편집증

계약에 의한 설계

Design By Contract, DBC. 계약과 계약의 조건. 그리고 변하지 말아야 할 것과 변하지 않는것에 대한 약속

선행 조건 후행 조건 클래스 불변식
  • 직교성
  • 죽은 프로그램은 거짓말을 하지 않는다
  • 단정적 프로그래밍
  • 리소스 사용의 균형
  • 결합도 줄이기와 디미터 법칙
  • 시간적 결합
  • 우연에 맡기는 프로그래밍
  • 테스트하기 쉬운 코드
  • 실용주의 팀

죽은 프로그램은 거짓말을 하지 않는다

절대 일어날 리 없는 일은 없다. 망치지 말고 일찍 작동을 멈춰라. 한박자 쉬기

  • 계약에 의한 설계
  • 언제 예외를 사용할까

단정적 프로그래밍

단정문(Assert)을 사용해서 불가능한 상황을 예방하라. 그러나 에러처리 대신으로 단정을 사용하지 마라.

  • 디버깅
  • 계약에 의한 설계
  • 리소스 사용의 균형
  • 우연에 맡기는 프로그래밍

언제 예외를 사용할까

예외처리는 정상적인 로직이 에러처리에 묻히는것을 막아준다. 꼭 있어야 하는것에 대한 에러는 예외처리를 해 프로그램을 중단시키고 아닌것은 에러처리를 해서 프로그램을 진행시킨다.

  • 죽은 프로그램은 거짓말을 하지 않는다

리소스 사용의 균형

시작한것은 끝내기. 리소스를 하나의 클래스로 감싸라. 그리고 래퍼 클래스를 스택에 할당하라. 그러면 리소스가 힙이든 스택이든 행복한 상황

  • 계약에 의한 설계
  • 단정적 프로그래밍
  • 결합도 줄이기와 디미터 법칙

구부러지거나 부러지거나

결합도 줄이기와 디미터 법칙

결합도가 높은경우

public void bla(
	Selection aSelection){
	...
    aSelection
    	.getRecorder()
    	.getLocation()
    	.getTimeZone();
}

위의 코드는 괜히 Selection과 Recorder와 Location이 결합되어 있다. 이렇게 하지 말고 TimZone을 바로 넘겨라. 그렇게 모듈간의 결합도를 최소화하라.

메타 프로그래밍

메타데이타를 이용해서 통합하지 말고 설정데이타를 잡고 설정하라. 메타데이타를 가지고 애플리케이션을 기술 할 수 있다. 메타데이타 주도적 프로그래밍을 하라.

  • 직교성
  • 가역성
  • 도메인 언어
  • 일반 텍스트의 힘

시간적 결합

작업흐름과 그에따른 시간적 결합에 주의하고 작업흐름을 분석하여 동시성을 개선하라. 작업들을 모아야하는 곳에서는 중계자나 칠판을 두는것도. 흐름의 수직적인 측면과 수평적인 측면(동시성)을 고려하여 설계하라.

  • 계약에 의한 설계
  • 우연에 맡기는 프로그래밍

단지 뷰일 뿐이야

이벤트는 단지 알림, 이벤트 수신을 위한 인터페이스를 고려 - 옵져버 패턴 - 하라. 모델에서 뷰를 분리하고 뷰는 단지 뷰일 뿐이다.

  • 직교성
  • 가역성
  • 결합도 줄이기와 디미터 법칙
  • 칠판
  • 결국은 모두 글쓰기

칠판

읽고 쓰고 가져올수 있는 칠판을 활용하여 작업흐름을 조율하라. 그리고 칠판은 객체에게 알릴수 있게 하라. AiWisdom 의 BBWar 가 칠판시스템을 이용하여 작성되었다.

코딩하는 동안 해야 할 일들

우연에 맡기는 프로그래밍

우연에 의한 잘못된 결론을 내리지 말도록 의도적으로 프로그래밍하라. 의도적 프로그래밍이란

  • 내가 지금 무엇을 하고 있는지 알아야 한다.
  • 맹목적으로 코딩하지 않는다.
  • 계획을 세우고 그것을 바탕으로 진행한다.
  • 신뢰할 수 있는 것에만 기대한다.
  • 가정은 문서로 남긴다.
  • 코드뿐만 아니라 가정도 테스트 한다.
  • 노력을 기울일 대상의 우선순위를 정한다.
  • 과거의 노예가 되지 말고 더 이상 적절한 코드가 아니라고 판단되면 즉시 교체하라.

관련항목

  • 돌멩이 수프와 삶은 개구리
  • 디버깅
  • 계약에 의한 설계
  • 단정적 프로그래밍
  • 시간적 결합
  • 리팩터링
  • 결국은 모두 글쓰기

알고리즘의 속도

알고리즘의 차수를 추정하고 추정을 테스트하라. 코드 프로파일링 환경을 구축하라.

  • 추정

리팩터링

리팩터링을 해야할 때

  • 중복 - 산탄총 수술
  • 직교성이 좋지 않은 설계 - 확산적 변경
  • 유효기간이 끝난 지식
  • 성능

리팩터링이 이익을 얻는 쪽으로 되기 위해서

  • 새로운 기능추가를 동시에 하지 마라
  • 든든한 테스트 집합을 구축해 놔라
  • 단계를 작고 신중하게 나누어서 진행하라

관련항목

  • 고양이가 내 코드를 삼켰어요
  • 소프트웨어 엔트로피
  • 돌멩이 수프와 삶은 개구리
  • 중복의 해악
  • 직교성
  • 우연에 맡기는 프로그래밍
  • 테스트하기 쉬운 코드
  • 가차없는 테스트

테스트하기 쉬운 코드

소프트웨어를 만들때 처음부터 테스트 가능성을 만들어 넣고, 코드들을 서로 연결하기전에 철저한 테스트가 필요하다. 그런 테스트중에 동작을 분리시킨 단위테스트가 좋은데, 하나의 단위를 무엇으로 할지는 내 몫이다.

테스트 단위의 하나로 계약을 잘 지키는지를 테스트할 수 있다. 계약은 다음과 같이 구성된다.

  • 필요(require) (ex. argument > 0)
  • 확인할것(ensure) (ex. 행동의 리턴값)

단위 테스트 방법으로 자바의 경우는 자신만의 main 메쏘드를 가지고 그걸로 테스트를 하면 된다(자바 만세) 만일 이런것이 여의치 않으면 단위 테스트 셋을 구축하는것도 좋은 방법(따라서 Sample Application이나 log 메쏘드는 무척 중요하다.) 이러한 단위 테스트 셋중에 junit은 유명하며 꼭 배울 가치가 있을듯.

관련항목

  • 고양이가 내 코드를 삼켰어요
  • 직교성
  • 계약에 의한 설계
  • 리팩터링
  • 가차 없는 테스트

사악한 마법사

마법사는 훌륭하다. 그러나 마법사가 만들어 놓은 코드를 이해하지 못한다면 큰 낭패를 겪는다. 마법사가 만든코드를 이해없이 바꾸는것은 위험하다 - 바꿀때는 테스트를 여러번 해가며 변화 코드에 따른 주석을 남기며 하자. 자신이 완전히 이해하지 못한 코드는 나중에 발목을 잡을 것이다.

관련항목

  • 직교성
  • 코드 생성기

프로젝트 전에

요구사항의 구렁텅이

요구사항을 수집하지 말고 채굴하라. 채굴되는 요구사항은 ‘어떤것이 성취되어야 한다’라는 식의 진술이 가능한 것이다. 진술속에 정책이 포함되어 있다면 정책을 고정하는것은 그리 좋은 방법은 아니다. 따라서 요구사항정책은 구분하는것이 좋다. 아마, 정책은 메타데이타가 될것이다. 요구에 필요한 내재적 상황을 파악하라. 제일 좋은 방법은 사용자가 되는 것이다. 요구사항은 문서화가 될 필요가 있다. 물론 지나치면 좋지않다. (어쩌라고) 또 필요한 것중의 하나가 프로젝트 용어다. 프로젝트 용어사전을 사용하라. 더불어, 나는 요구사항을 한번에 알 수 없다고 생각한다. 따라서 프로토 타입을 거쳐 요구사항을 채굴하고 최종적으로 결과를 짓는것이 좋다고 생각한다.

관련항목

  • 돌멩이 스프와 삶은 개구리
  • 적당히 괜찮은 소프트웨어
  • 동그라미와 화살표
  • 결국은 모두 글쓰기
  • 위대한 유산

불가능한 퍼즐 풀기

제약들을 범주별로 나누고 우선순위를 매겨라. 불가능해 보이는 퍼즐에 마주쳤다면, 새로운 생각의 을 찾아라.

  • 더 쉬운 방법이 존재하는가?
  • 진짜 문제를 풀려고 노력하고 있나. 그렇지 않다면 중요하지 않은 기술적 문제에 정신이 팔려 있는 것인가?
  • 왜 이것이 문제있가?
  • 문제를 이렇게 풀기 어렵게 만드는 것이 무엇인가?
  • 반드시 이 방법으로 해야 하는가?
  • 반드시 해야 하는 일이긴 한가?

준비가 되어야만

준비가 되었을때 시작하라. 그런데 준비는 무엇일까? 어떤것이 준비되어있음 일까? 효과적인 준비에 프로토타이핑이 있다. 프로토타입을 통해 개념이 틀렸거나 좋다는 입증을 할 수도 있고, 생각하지도 못했던 기법들을 적용할 수 도 있다. 더구나 비용도 적다!(그래도 일주일 정도는 걸리겠지만..) 또한, 프로토타입작업은 결과물이 있다는 점에서 정치적으로도 어느정도 용인이 된다.

명세의 함정

명세화는 주요한 모호함들을 제거하는 등의 방법으로 세계를 설명하고 명확하게 만드는 의사소통의 한 행위. 의사소통이 필요한자 - 구현자, 유지보수자, 요구자 - 를 위한 기록. 한번에 모든 명세를 알아낼 수는 없다. 사람들간의 해석차이가 존재하며 언어 자체의 표현능력에도 한계가 있다.

  • 어떤 일들은 설명하기보다 실제로 하는것이 쉽다. 또한 코딩하는 도중에서야 어떤 선택 가능성들이 분명하게 드러나는 경우가 많다.
  • 기본적인 명세방법 : 요구사항 수집 - 명세 - 코딩시작
  • 실용주의적 방법 : 명세화 - 구현/테스트 - 다시 명세화

프로토타이핑이나 예광탄 개발을 하는것을 권장.

관련항목

  • 예광탄

동그라미와 화살표

형식적 방법의 노예가 되지 마라. 형식적인 방법은 도구상자 속의 또 다른 도구이다. 비싼 도구가 더 좋은 설계를 낳지는 않는다. 역시 연습장 설계 쵝오.

관련항목

  • 요구사항의 구렁텅이

실용주의 프로젝트

프로젝트 차원의 활동들을 일관성 있고 신뢰할 만하게 하는 가장 중요한 요소는 일의 과정을 자동화 하는것. 또한 단계를 나누고 다음 단계로 넘어가는 테스트를 마련하는것도 중요.

실용주의 팀

  • 깨진 창문을 없애라 - 품질에 대한 책임성
  • 삶은 개구리 - 남에게 미루거나 등등. 환경변화에 팀은 쉽게 무뎌질 수 있다.
  • 소통하라! 프로젝트를 시작할때 재미있는 이름을 지어주는것도 한가지 방법.
  • 반복 - 중복 - 하지 마라
  • 직교성 - 팀을 기능 중심으로 조직하라
    • 계약에 의한 설계
    • 결합도 줄이기와 디미터 법칙
    • 팀의 변화가 전체 변화에 큰 영향을 받지 않도록.
    • 팀에는 적어도 우두머리2명 필요 - 하나는 기술담당 / 다른 하나는 관리담당
  • 자동화 - 자동화 도구를 만들고 조직화하라
  • 덧칠을 언제 멈출지 알아라 - ‘적당히 괜찮은 소프트웨어’ 만들기

관련항목

  • 소프트웨어 엔트로피
  • 돌멩이 스프와 삶은 개구리
  • 적당히 괜찮은 소프트웨어
  • 소통하라!
  • 중복의 해악
  • 직교성
  • 계약에 의한 설계
  • 결합도 줄이기와 디미터 법칙
  • 유비쿼터스 자동화

유비쿼터스 자동화

프로젝트에서 일관성과 반복가능성은 중요하다. 그러나 수작업은 이 둘을 어렵게 만든다. 특히 이 과정이 여러사람들에 의해 다르게 해석될수록 더욱 심해진다. 소스를 자동으로 만드는 스크립트를 작성하는것은 어떠신지? 혹은 이런 프로그램들을 만들면 좋을것 같다.(TODO) 테스트 절차를 자동화 할 수 있는 빌드 스크립트를 만들어라. 코딩을 하는것이 개발이 아니다. 개발에는 코딩이외에 반복되는 절차 - 문서를 작성한다든지 - 가 있다. 이러간 개발절차자동화 하라. 쓸모있는 정보를 만들어내는 절차를 자동화 하라.

  • 코드와 관련된 문서
  • 요구사항 분석
  • 설계문서, 그림, 차트, 그래프 등

cron, make, perl등의 스크립트 언어들을 잘 활용하자.

관련항목

  • 고양이가 내 소스코드를 삼켰어요
  • 중복의 해악
  • 일반 텍스트의 힘
  • 조개놀이
  • 디버깅
  • 코드 생성기
  • 실용주의 팀
  • 가차 없는 테스트
  • 결국은 모두 글쓰기

가차 없는 테스트

일찍 테스트하고, 자주 테스트하라. 자동으로 테스트 하라.

와우. 잘 짠 테스트를 통과한 코드의 품질은 보증된다. 모든 테스트가 통과하기 전엔 코딩이 다 된 게 아니다.

무엇을 테스트할지 - 히야. 중요하다네.

  • 단위 테스트
  • 통합 테스트
  • 유효성 평가(validation)와 검증(verification)
  • 자원고갈, 에러, 그리고 복구
  • 성능(performance) 테스트
  • 사용 편의성 테스트

어떤 한 단위가 다른 단위에 영향을 줄 수도 있다. 그런데, 줄 수 있는 영향이 달라지면 어떻게 되나? 그 영향을 전제로 테스트를 했다면 영향을 받는것을 모두 조사해야 할 것이다. 완전한 확산적 변경이다. 이러한 테스트를 통합테스트라고 하고 계약에 의하며 계약이 제대로 행해지는지를 테스트 한다. 유효성 평가를 반드시 하라. 사용자 인터페이스나 프로토 타입이 갖추어 지자마자 그제 정말로 필요한 기능이었는지에 대한 유효성에 대해 평가하라. 실패에 대한 사항들도 테스트하라.

어떻게 테스트할까 - 역시 중요하다네.

  • 회귀 테스트
  • 테스트 데이터
  • GUI 시스템 구동
  • 테스트를 테스트하기
  • 철저히 테스트하기
  • 사용 편의성 테스트

…계속

결국은 모두 글쓰기

위대한 유산

오만과 편견


컴퓨터 프로그래밍