실용주의 프로그래머 6. 코딩하는 동안 해야 할 일들

jiffydev·2021년 8월 4일
0

1. 우연에 맡기는 프로그래밍

코드를 작성할 때 이 코드가 왜 잘 돌아가는지를 인식하면서 작성하는가?
코드를 작성하다보면 이따금 루틴을 의도에 맞지 않게 호출해도 원하는 동작을 하는 것처럼 보일 때가 있다.
이렇게 우연히 잘 동작하는 것을 확인하지 않고 내버려 두게 되면 분명 어디선가 문제가 생기게 된다.

실용적인 프로그래머라면 코드가 잘 돌아가는 것을 우연에 맡기지 않는다.

  • 항상 자신이 지금 무엇을 하고 있는지 알고 있다

  • 계획을 바탕으로 진행한다

  • 신뢰할 수 있는 것에만 기대고, 가정에 의존하지 않는다

  • 가정을 문서로 남기고 테스트한다

  • 중요한 것들에 시간을 투자한다

  • 과거의 코드에 연연하지 않고 언제나 수정할 준비가 되어 있다.

2. 알고리즘의 속도

입력의 크기는 알고리즘의 속도에 영향을 준다.
다만 영향은 선형적이 아니기에 선형보다 증가폭이 작을수도, 훨씬 클수도 있다.
그래서 알고리즘의 수행시간을 확인하기 위해 사용할 수 있는 방법 중 하나가 빅오 표기법(Big O notation)이다.

사실 일을 하면서 정렬 알고리즘을 직접 구현하는 경우는 많지 않을 것이다.
하지만 위의 알고리즘 시간 복잡도를 이해하고 있으면 입력의 규모에 따라 시간이 얼마나 걸릴지 예측이 가능하고, 이를 바탕으로 실무에서 실제 입력 데이터의 규모에 따라 알고리즘을 선택할 수 있을 것이다.

3. 리팩터링

코드는 동적이기 때문에 프로그램이 발전해가면 코드의 일부분을 다시 작성해야 할 일이 생긴다.
코드를 다시 작성하고, 다시 작업하고, 다시 설계하는 과정을 통틀어 리팩터링이라고 한다.

그렇다면 언제 리팩터링을 해야 할까?
뭔가 잘못되었다 싶으면 당장 리팩터링에 들어가야 한다.
그 외에는 중복이 발생했거나 직교적이지 않은 코드, 유효기간이 끝난 지식, 성능 저하가 발생했을 때 수행할 수 있다.

리팩터링은 기존의 코드를 해체하는 것이기 때문에 이를 주저하는 경우가 많고, 실제로 내가 작성한 코드를 다 없애버리고 새로 시작하는 것은 고통스러운 작업이다.
하지만 이는 다가올 미래의 고통을 지금 최소한으로 줄일 수 있는 것이기에 꼭 필요한 일이다.
따라서 항상 리팩터링 할 것들의 명단을 만들고 최대한 일찍, 자주 리팩터링해야 한다.

리팩터링은 코드의 재설계다. 그렇다고 아무 부분이나 마구잡이로 삭제할 수는 없으니 어떻게 리팩터링을 하는가도 중요한 문제이다.
마틴 파울러가 제안한, 손해보다 이득이 더 큰 방향으로 리팩터링하기 위한 아래의 방법을 참고할 만하다.

  • 리팩터링과 새 기능추가를 동시에 하지 않는다

  • 리팩터링 전에 든든한 테스트 집합이 있는지 먼저 확인하고, 자주 테스트를 돌린다

  • 단계를 작게 나누어 신중하게 작업하고, 각 단계가 끝날 때마다 테스트를 돌린다

4. 테스트하기 쉬운 코드

소프트웨어를 만들 때도 처음부터 테스트가 가능하도록 하고, 각 코드를 연결하기 전에도 테스트가 필요하다.
소프트웨어에서는 단위테스트를 통해 동작을 검증할 수 있는데, 인위적 환경을 구축한 후 테스트할 모듈을 호출해 이미 알고 있는 값과 결과를 비교해 보는 방식이다.

그런데 단위테스트를 할 때 아무 데이터나 넣어서 테스트하면 테스트의 의미가 없다.
따라서 이전에 설명한 '계약에 의한 설계'를 기반으로 테스트하는 것이 바람직하다.
또한 모듈을 설계할 때는 계약을 지키는지 테스트하는 코드도 함께 설계해야, 그렇지 않았을 때보다 에러가 발생할 가능성을 줄일 수 있다.

단위테스트를 작성할 때는 우선 테스트를 찾기 편한 위치에 보관해야 한다.
테스트가 찾기 편해야 작성한 테스트를 보고 모듈이 어떻게 동작하는지 파악할 수 있고, 코드를 변경했을 때도 검증하기 쉽기 때문이다.

테스트 집합을 아무리 잘 만들어도 어디선가 버그는 발생한다.
그래서 소프트웨어가 배포된 후에도 테스트해야 하는 경우도 발생하는데, 이 때 사용할 수 있는 방법이 몇 가지 있다.
먼저 로그 파일을 생성하는 방법인데, 주의해야 할 점은 규칙적이고 일관된 형식으로 로그 메시지를 작성해야 한다는 것이다.
다음으로 실행중인 코드의 내부로 들어갈 수 있는 단축키를 제공함으로써 상태 정보가 들어있는 창이 열리도록 하는 방식이다.
마지막으로 규모가 큰 서버 코드라면 웹 서버를 내장시켜 외부에서도 웹브라우저를 통해 상태를 확인할 수 있도록 하는 방법이 있다.

5. 사악한 마법사

애플리케이션이 날이 갈수록 복잡해지면서 수많은 요구사항을 충족시켜야 하게 되었다.
이런 상황에서 소위 '마법사'를 사용하면 엄청난 양의 코드를 자동으로, 그것도 깔끔하게 생성해 줄 수 있다.
그런데 이와 같은 마법사는 항상 개발자에게 득이 될까?

만약 개발자가 생성된 코드를 제대로 이해하지 못했다면 아무리 좋은 코드라도 유지보수, 디버깅이 불가능해지므로 무용지물일 것이다.
물론 세상에는 원리를 완벽하게 이해하지 못하고도 기술을 잘 활용하는 경우가 있지만, 마법사가 생성하는 코드는 조금 다르다.
이렇게 생성된 코드는, 개발자가 작성한 코드와 애플리케이션에서 한데 섞여 풀 수 없는 코드가 되기 때문이다.
따라서 반드시 자신이 이해한 코드를 사용하도록 해야 한다.

profile
잘 & 열심히 살고싶은 개발자

0개의 댓글