제대로된 코드를 만들기 위해서는 제대로된 코드를 많이 읽어보면 된다.
큰 그림을 보자
개별 단위 함수부터 보는 대신 튜토리얼, 문서, 코드 이외의 다른 참고자료부터 살펴보자.
프로젝트 구조 파악이 우선이다.
코드 계층 구조를 파악하고 어떤 코드가 어떤 코드를 import 하는지, namespace는 어떻게 명명되어 있는지를 살펴보자.
내가 이프로그램을 만든다면 어떻게 만들까 고민
찾아낸 사실을 문서로 만들자.(ppt, flowchart, 구성도, 마인드맵)
찾아낸 사실을 문서로 만들고 프로그램 흐름에 맞춰 가정과 결론을 나중에 찾아볼 수 있게 주석으로 달아놓자.
분석을 하면서 그림/ 문서로 정리를 하자.
중간 중간 정리해 나가면 머리 속에 생각이 정리 될때가 많다.
테스트를 사용하자
테스트는 출발점으로 적절하다. 코드 읽기에 앞서 테스트를 돌려서 환경이 제대로 구성되어 있는지 확인할 필요가 있다.
테스트에 앞서 빌드부터 성공해야한다.
실행하고, 변경하고, 다시 실행하자(Refactoring-rewrite chunk)
나라면 어떻게 짰을까?
뭘 배웠나?
이 코드를 어떻게 하면 개선할 수 있을까?
원 작성자의 스타일로 코드를 작성해보자
=> 위 네가지 단계에 대해 직접 적어보자.
모든 것을 분해했다면 다시 조립하면서 이해도를 높이자. 기능을 추가해서 테스트 통과여부를 살펴보자. 다양한 코드 상태를 확인할 수 있게 로그 수준을 높여보자.
예시로 병아리 감별사의 성장기를 들고있다.
(새로 온) 병아리감별사가 충분히 피드백에 노출되었을 때, 뇌는 무의식적으로 패턴과 기본 구조를 알아낸다.
더 많은 노출되면, 뇌는 그 지각력을 미세하게 조정하고, 결국 무엇이 진짜인지 알아낸다. 뇌는 설명할 수 없더라도 더 미세하게 구별하고 소음과 신호를 구별한다.
지각적 지식은 우리가 생각하는 전문적인 직관을 포함한다.
비록 알고있는것을 정확히 말할 수는 없지만 어떤 체스를 즉시 움직여야 할지 혹은 이 그림이 위조품이라는 것, 혹은 이 집이 폭발할 것이라는 것 혹은 코드에 문제가 있다는 것 등 이런 능력들이 있다.
프로그래밍을 오래할수록, 코드 샘플을 많이 볼수록, 다른 사람의 코드를 이해하기 쉬워지고 빨라진다.
또한 레퍼런스 활용에도 강점을 갖고 과거의 코드를 한눈에 이해하게된다.
레거시 코드로 일하는 것은 거대한 직소 퍼즐을 푸는 것과 비슷하다.
모든 퍼즐 조각들 한꺼번에 펼쳐놓고 맞추려 들면 도통 진도가 나가지 않는다.
각 조각을 그룹으로 나누고 모서리나 경계선부터 시작해야 한다.
조각들을 색상이나 패턴을 기준으로 분리해서 모아두어도 도움이 된다.
몇 가지 작은 그룹들이 만들어지면 큰 형태가 머릿 속에 그려진다.
시작할 때는 한 무더기의 무작위적인 조각 모음이었지만 약간은 정리된 작은 그룹들의 조각 모음으로 만들 수 있다.
각각의 작은 그룹들에 대해서 조금씩 조각을 맞춘다.
즉 점진적으로 기존 코드에 대한 테스트 코드를 작성하면서 코드에 대한 이해도를 높이고 리펙토링을 해나간다.
몇몇 조각들을 맞추는 데 성공하면 전체 그림의 일부분을 볼 수 있다.
이 단계에서는 뭔가 실질적으로 손에 잡히는 것을 얻을 수 있기 때문에 조금 더 자신감이 생긴다.
코드도 이해되기 시작하고 업무 진척도 빨라진다.
이어 붙인 조각들이 많아질수록 남은 조각들을 이어붙이기가 더 쉬워지고, 전체 직소 퍼즐의 완성 형태가 보이기 시작한다.
레거시 코드를 다루는 것은 직소 퍼즐을 맞추는 것과 너무나도 비슷하다.
개선하는 코드 조각이 하나씩 늘어날 때마다 코드 전체를 개선하고 싶은 욕구가 일어난다.
이러한 성취감은 큰 보상이 된다.
처음에는 그냥 보는 것만으로도 벅차던 코드가 이제는 특별한 노력이 없어도 소설책을 읽듯이 스토리까지 이해된다.
코드의 중요 부분이 안정화되면(테스트 코드로 검증되고, 과도한 종속성이 해소되고, 역할이 제대로 정의되는 등) 사용하고 싶었던 새롭고 멋진 프레임워크를 도입하는 것이 가능할 수도 있다.
라이브러리의 버전을 업그레이드할 수도 있다.
코드가 깨끗하게 정리되고 모듈화된 상태에서는 프레임워크를 도입하여 상당 부분의 코드를 폐기하거나 시스템의 한 부분을 완전히 대체할 수도 있다.
이것이 가능한 이유는 코드가 정리되면서 한 부분의 수정이 나머지 부분에 영향을 미치지 않게 되기 때문이다.
이정도까지 진행되면 그린필드 프로젝트를 맡고 있는 다른 개발자를 부러워할 필요가 없어진다.
레거시 코드는 우리가 다른 방식으로 생각하도록 강제한다는 특징이 있다.
그린필드 프로젝트에서는 기능을 개발할 때 테스트를 작성하고 기능을 구현하기 시작한다.
그런데 레거시 코드에서는 얽혀 있는 종속성 때문에 테스트를 하기 위한 클래스 인스턴스 생성조차 벽에 부딪힐 수 있고,
특정 부분의 수정이 예상하지 못한 형태로 애플리케이션의 다른 부분에 영향을 미친다.
이때 우리는 두 가지 관점 중 하나를 선택할 수 있다.
하나는 지금 하고 있는 일을 고통스런 전생의 업보로 보는 것이고
다른 하나는 재미있고 도전적인 문제로 바라 보는 것이다.
우리는 후자를 선택해야 한다.
남이 작성한 코드를 엉망이라고 그냥 말하기는 쉽다.
심지어 비웃을 수도 있다.
하지만 나라면 더 잘 만들 수 있는가? 라고 스스로에게 물어보아야 한다.
Sometimes, the only way to understand someone else's code (when it is pretty bad) is by rewriting it yourself
좋은 글 읽고 갑니다. 감사합니다