14장 점진적인 개선
점진적인 개선에 대한 사례를 보여주는 챕터.
시작은 좋지만 확장성이 부족한 모듈을 개선하고 정리 했던 과거 일로,
Args 클래스를 작성한 저자의 코드를 예를 들어 하고싶은 말이 무엇인지 알아야 한다.
목차
- Args 구현
- 어떻게 짰느냐고?
- Args: 1차 초안
- 그래서 멈췄다
- 점직적으로 개선하다
- String 인수
14-1. Args 구현
public static void main(String[] args) {
try {
Args arg = new Args("l,p#,d*", args);
boolean logging = arg.getBoolean('l');
int port = arg.getInt('p');
String directory = arg.getString('d');
executeApplication(logging, port, directory);
} catch (ArgsException e) {
System.out.print("Argument error: %s\n", e.errorMessage());
}
}
매개변수를 두 개로 Args 클래스의 인스턴스를 만든다.
ArgsException이 발생하지 않는다면 Args 인스턴스에 질의를 던져도 좋다.
인수 값을 가져오기 위해 get 메서드를 사용한다.
단순한 개념을 구현하는데 코드가 너무 많이 필요해 놀랄지도 모른다.
우선적으로 장황한 언어인 자바를 사용해서이며 정적 타입 언어라서 타입 시스템을 만족하려면 많은 단어가 필요하다.
14-1-1. 어떻게 잤느냐고?
독자들이 깨끗하고 우아한 프로그램을 한 방에 뚝딱 내놓으리라 기대하지 않는다.
수십여 년 동안 쌓아온 경험에서 얻은 교훈이라면, 프로그래밍은 과학보다 공예에 가깝다는 사실이다.
깨끗한 코드를 짜려면 먼저 지저분한 코드를 짠 다음에 정리해야 한다는 의미이다.
깔끔한 작품을 내놓으려면 단계적으로 개선해야 한다.
대다수의 프로그래머는 이 충고를 충실히 따르지 않는다.
무조건 작동하는 프로그램을 목표로 잡는다.
‘돌아가는' 프로그램은 그 상태가 어떻든 그대로 버려둔다.
경험이 풍부한 전문 프로그래머라면 이러한 행동이 전문가로서 자살 행위라는 사실을 잘 안다.
14-2. Args: 1차 초안
지저분한 코드를 보고 처음 든 생각이 ‘코드의 작성자가 그냥 버려두지 않아서 진짜 다행이다' 이기를 바란다.
만약 그렇다면 자신이 대충 짜서 남겨둔 코드를 남들이 어떻게 느낄지 생각하길 바란다.
처음부터 지저분한 코드를 짜려는 생각은 없었다.
함수 이름이나 변수 이름을 선택한 방식, 어설프지만 나름대로 구조가 있다는 사실 등이 내 노력의 증거다.
어느 순간 프로그램은 내손을 벗어나 bool 인수만 지원하면 초기 버전에서 String과 Integer 인수 유형을 추가하면서 재앙이 시작된다.
14-2-1. 그래서 멈췄다
추가할 인수 유형이 더 있었는데 그러면 코드가 더 나빠지리라는 사실이 확실했다.
프로그램은 어떻게든 완성하겠지만 그랬다가는 손대기 어려운 골칫거리가 생겨날 참이었다.
그래서 기능을 더 이상 추가하지 않기로 결정하고 리펙터링을 시작했다.
인수 유형은 다양하지만 모두가 유사한 메서드를 제공하므로 클래스 하나가 적합하다 판단하여 ArgumentMarshaler라는 개념이 탄생했다.
14-2-2. 점직적으로 개선하다.
프로그램을 망치는 가장 좋은 방법 중 하나는 개선이라는 이름 아래 구조를 크게 뒤집는 행위다.
어떤 프로그램은 그저 그런 ‘개선'에서 결코 회복하지 못한다.
그래서 나는 테스트 주도 개발(Test-Driven Development : TDD)라는 기법을 사용했다.
TDD는 언제 어느 때라도 시스템이 돌아가야 한다는 원칙을 따른다.
다시 말해, TDD는 시스템을 망가뜨리는 변경을 허용하지 않는다.
변경을 가한 후에도 시스템이 변경 전과 똑같이 돌아가야 한다는 말이다.
14-3. String 인수
String 인수를 추가하고 Args 클래스에서 코드 중복을 최소화하고, 상당한 코드를 Args 클래스에서 ArgsException 클래스로 옮겼다.
소프트웨어 설계는 분할만 잘해도 품질이 크게 높아진다.
적절한 장소를 만들어 코드만 분리해도 설계가 좋아진다.
관심자를 분리하면 코드를 이해하고 보수하기 훨씬 더 쉬워진다.
결론
그저 작동하는 코드만으로는 부족하다.
작동하는 코드가 이후에 망가는 사례는 흔하다.
나쁜 코드보다 프로젝트에 악영향을 미치는 것은 없다.
나쁜 일정은 다시 짜면 되고 나쁜 요구사항은 다시 정의하면 되고 나쁜 팀 역학은 복구하면 된다.
하지만 나쁜 코드는 그대로 놔두면 부패한다.
나쁜 코드를 깨끗한 코드로 개선할 수 있지만 비용이 엄청나게 많이 들어간다.
하지만 5분 전에 엉망으로 만들어 놓은 코드는 지금 당장 정리하기 아주 쉽다.
코드는 언제나 깔끔하고 단순하게 정리해야한다.
이말을 저자는 과거 자신의 Args 클래스 사례를 예로 들어 설명하는 것 같다.
15장 Junit
'Etc > Clean Code[ Robert C. Martin ]' 카테고리의 다른 글
[Clean Code] 16장 SerialDate 리펙터링 (0) | 2022.05.14 |
---|---|
[Clean Code] 15장 JUnit 들여다보기 (0) | 2022.05.12 |
[Clean Code] 13장 동시성 (0) | 2022.05.09 |
[Clean Code] 12장 창발성 (0) | 2022.05.01 |
[Clean Code] 11장 시스템 (0) | 2022.04.18 |