메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일

프로그래밍 스타일(3)

한빛미디어

|

2005-09-26

|

by HANBIT

14,166

저자: 한동훈

[지난기사보기]
프로그래밍 스타일(2)
프로그래밍 스타일(1)

1.5 코드에 집중하지 마라

프로그래머는 대개의 경우에 코드에 집중해야한다. 그러나 실제로 프로그래머가 집중해야할 것은 설계다. 몇일전 술자리에서 얘기한 것처럼, 필자는 하루종일 조용히 모니터를 쳐다보고 종이에 끄적이다가 퇴근하기 1-2시간 전에 사무실을 날려버릴 것과 같은 키보드 소음공해를 일으키고 온다고 했다. 심지어는 머리가 맑을 때 코드를 작성하는 것이 아니라, 가장 졸리고 신경 안 쓰는 일을 할 때 코드를 작성한다. 아니, 코드를 작성하는 것은 지극히 단순 노동이라고 얘기하곤 한다. - 물론, 실제로 100% 맞는 말은 아닐 것이다. -

실제로 여러분이 해야할 일은 설계다. 코드를 작성하기 전에, 함수 하나 작성하기 전에 여러분은 설계에 집중해야한다.

직원들의 급여를 계산하는 함수를 작성하는 경우를 예로 들어보자. 처음에는 함수의 이름을 먼저 생각한다. 그리고 함수가 무엇을 할지를 쓰게 된다. 그리고 그 순서는 다음과 같을 지도 모른다.

1차 - 기본적인 로직을 생각한다

CalculatePay()
   사원 ID를 받는다.
   사원 ID에 따른 직급을 구한다.
   직급에 따른 월급을 구한다.
   월급을 반환한다.

2차 - 요구사항(직급)에 대한 로직을 추가한다

급여를 사원 ID에 따라 계산한다
CalculatePay(사원ID)
   필요한 변수를 선언한다
   사원 ID에 따른 직급을 구한다.

   직급에 따른 월급을 분류한다.
      사장
      과장
      대리
      사원
구한 월급을 반환한다.

3차 - 오류검사를 추가했다

급여를 사원 ID에 따라 계산한다
CalculatePay(사원ID)
   필요한 변수를 선언한다
   사원 ID가 맞는지 확인한다
      ID가 맞으면 사원 ID에 따른 직급을 구한다.
      틀리면 에러로 넘긴다.

   직급에 따른 월급을 분류한다.
      사장
      과장
      대리
      사원

전체에서 예외가 발생했으면 예외처리로 넘긴다.
전체에서 예외가 발생하지 않았으면 구한 월급을 반환한다.

4차 - 결근, 지각, 조퇴인 경우의 급여계산을 한다

급여를 사원 ID에 따라 계산한다
CalculatePay(사원ID)
   필요한 변수를 선언한다
   사원 ID가 맞는지 확인한다
      ID가 맞으면 사원 ID에 따른 직급을 구한다.
      틀리면 에러로 넘긴다.

   직급에 따른 월급을 분류한다.
      사장
      과장
      대리
      사원

결근인 경우에
      횟수 n만큼의 결근기준급여를 삭감한다
지각인 경우에
      횟수 n만큼의 지각기준급여를 삭감한다
조퇴인 경우에
      횟수 n만큼의 조퇴기준급여를 삭감한다

전체에서 예외가 발생했으면 예외처리로 넘긴다.
전체에서 예외가 발생하지 않았으면 구한 월급을 반환한다.

실제로는 이 외에도 연봉액, 연봉액기준기간, 근무자의 근로일과 근로시간, 지불방법, 각종 수당의 종류와 처리 방법, 연봉 대상기간 도중에 퇴직시의 급여계산 방법들이 나올 것이다.

이와 같이 하나의 함수를 업무 로직에 따라 천천히 확장해가면서 작성하는 방법은 좋은 방법이다. 또한 코드가 아니라 의사코드이기 때문에 이해하는데 큰 무리가 발생하지 않는다. 만약, 이것을 처음부터 코드로 작성하면서 복잡한 급여계산을 처리하려 했다면 코드 작성시간 뿐만 아니라 문제가 발생했을 때의 버그 해결 시간도 길어질 것이다.

이와 같은 로직을 모두 작성하고 문제가 없다고 판단되면 워드에서 출력을 하고, 도서 받침대 같은 곳에 올려놓고 그대로 타이핑해 나가면 될 것이다. 자신이 사용하는 언어에 따라 적절한 문법에 따라 코드로 옮겨놓기만 하면 될 것이다.

이것으로 무엇을 할 수 있었는가? 전체의 설계를 할 수 있었다. 또한, 코드를 작성하기 전에 한 번 점검함으로써 예상치 못한 부분들에 대해서도 생각해 볼 수 있었고, 그에 대한 문제도 적절히 처리할 수 있었다. 위의 의사 코드를 보면 들여쓰기가 되어있을 것이다.

그렇다, 위 의사 코드를 에디터에 그대로 옮겨놓고, 모두 주석 표시를 해주고, 문장 중간 중간에 코드를 써 넣어라. 그러면 된다. 이것으로 여러분이 작성한 코드는 조금 더 버그가 적어질 수 있고, 주석이 풍부한 코드가 될 수 있다.

1.5.1 코드 오염의 최소화

한가지 변경 사항이 발생했을 때 코드의 한 곳을 수정하는 것이 아니라 여러 곳을 모두 수정하는 것은 코드 오염의 전형적인 현상이다. 때문에 좋은 코딩이란 코드 오염을 최소화하는 것이라 할 수 있다. 이것은 좋은 설계에 해당하기도 한다.

4차에서는 몇 곳을 강조해두었다. 해당 부분들은 급여 계산외의 다른 부분에서도 굉장히 자주쓰이는 코드가 될 것이라고 예상되기 때문이다. 이런 코드들은 다른 부분에서 굉장히 자주 중복될 것이고, 이런 중복된 코드는 하나의 메서드로 작성하는 것이 좋다. 하나의 메서드로 작성하면 코드 중복을 최소화할 수 있고 변경사항이 발생했을 때 변경하기도 쉽다.

"사원 ID가 맞는지 확인한다"는 CheckEmpID() 함수로 만들 수도 있다. 하지만, 이런 함수는 단순히 검사만 수행하는지 결과값을 반환하는지 알 수 없다. 디스크 검사를 수행하는 CheckDisk() 함수와 명확히 구별되지 않는다. 이것이 하드 디스크인지 알아내는데 IsHarddisk()와 CheckHarddisk() 함수 이름을 보면 어떤 것이 더 나은지 알 것이다.

IsValidEmpID() 함수와 같은 이름으로 별도의 함수를 만들면 좋다.

"사원 ID에 따른 직급을 구한다" 이 함수는 특정 기준(사원ID)에 따라 직급을 구하는 것이니 GetGrade(사원ID) 라는 이름을 사용할 수 있을 것이다. 그러나, 직급의 이름(대리, 과장, 부장)에 따른 직급을 구하는 함수가 필요할 때 GetGrade(직급명)으로 함수를 작성할 수 없을수도 있다. - 모든 언어가 객체지향의 특징을 제공하는 것이 아니다. PHP4도 그런 예이다 - 때문에 GetGradeByID, GetGradeByName과 같은 함수 명도 사용할 수 있다.

- 나는 급여 계산과 관련한 코드를 작성한 경험이 없다. 이러한 방법을 설명하기 위해 실질적인 예를 드는 방법(OS의 스케줄링이나 가상 메모리 관리 코드)도 있겠지만 지나치게 특정 언어/플랫폼에 종속되어 논지를 전달하기 어렵다고 생각하기 때문에 급여 코드를 기준으로 설명하였다 -

1.6 꾸준히 하기

프로그래머가 짓고 있는 죄 중에 가장 큰 죄가 무엇인가? 그것은 꾸준히 하지 못한다는 것이다. 대부분의 프로젝트는 원대한 꿈(?)을 갖고 시작하지만, 결국에는 마감시간안에 끝내기에 급급하다는 것이다. 그래서 처음에 세웠던 계획대로 코딩을 하지 못하고, 설계에 들이는 시간보다 막바로 코딩을 하기에 바쁘고, 수정한 코드들에 대해서 주석을 남기지 않는 실수를 하게 된다. 그래서 나중에는 코드와 주석에 설명된 내용이 전혀 엉뚱하게 되어버리는 경우도 생기게 된다.

그리고 무엇보다 가장 큰 문제는 시간이 흘러서 예기치 못했던 곳에서 에러가 생긴다고 하는 것이다. 그리고 그 버그를 잡는데 들이는 시간이 여러분이 코드를 작성하는 데 들인 시간보다 더 많다는 것을 알게 될 것이다. 그것은 프로젝트의 끝이 아니다.

아무리 급해도 "빠르고 성급하게"가 아니라 "꾸준히 완전하게"하는 것을 목표로 삼아라.
TAG :
댓글 입력
자료실

최근 본 책0