파이브 라인스 오브 코드 - 1장+2장

이마닷·2024년 8월 10일
0
post-thumbnail

1장. 리팩터링 리팩터링하기

제목 오타 아님

좋은 코드(Good code) - 사람이 읽기 쉽고, 유지보수가 용이하며, 의도한 대로 잘 동작하는 코드

리팩터링(Refactoring) - 기능을 변경하지 않고 코드의 가독성유지보수가 쉽도록 코드를 변경하는 것

많은 사람들이 프로그래밍을 코드를 작성하는 것으로 생각하지만, 대부분의 프로그래머는 코드를 작성하는 것보다 코드를 읽고 이해하는 데 더 많은 시간을 보냅니다. 복잡한 분야에서 작업하기 때문에 이해하지 못하고 뭔가를 변경하면 뭔가 치명적인 장애가 발생할 수 있기 때문입니다.

리팩터링은 정기적으로 수행하는 것이 효과적이고 비용이 적게 들기 때문에 가능하면 일상 업무에 통합하는 것이 좋습니다.

이 책에 제시된 규칙은 자전거의 보조바퀴와 비슷한 역할을 합니다. 앞서 논의한 바와 같이 모든 상황에서 좋은 코드를 보장할 수 없으며, 어떤 경우에는 규칙을 따르는 것이 잘못될 수도 있습니다. 그러나 어디서 시작해야 할 지 모르는 경우에는 유용하고 멋진 코드 리팩터링의 이유를 제공합니다.

"우선 변경하기 쉽게 만든 후 변경하라"
새로운 것을 구현할 때마다 새 코드를 쉽게 추가할 수 있게 리팩터링을 먼저 합니다. 이것은 요리를 시작하기 전에 필요한 재료를 준비하는 것과 유사합니다

2장. 리팩터링 깊게 들여다보기

가독성은 의도를 전달하기 위한 코드의 성질입니다. 이 말은 곧 코드가 의도한 대로 작동하다는 가정이 있으면 코드가 무슨 일을 하는지 파악하기가 매우 쉽다는 뜻입니다.

버그를 고치거나 기능을 추가하기 위해 일부 기능을 변경해야 할 때마다 새 코드를 어디에 놓을지 후보 위치(context)를 조사하는 것으로 시작합니다. 유지보수성은 얼마나 많은 후보를 조사해야 하는지를 나타내는 표현입니다. 읽고 봐야 할 코드가 많을수록 시간이 더 오래 걸리고 무언가를 놓칠 가능성이 높다는 것은 쉽게 알 수 있습니다.

어떤 시스템에서는 한군데서 무언가를 수정하면 관련 없어 보이는 다른 돗에서 문제가 발생합니다. 그런 시스템을 취약하다(fragile)고 말합니다. 이 취약성의 근원은 일반적으로 전역상태(global state)입니다. 여기서 전역은 우리가 고려한 범위를 벗어난 것을 의미합니다.

코드에서 상태를 명시적으로 확인하지 않는 속성을 불변속성(invariant)라고 합니다. "이 숫자는 절대 음수일 수 없습니다"라든가 "이 파일은 확실히 존재합니다"는 불변속성의 예입니다. 안타깝게도 특히 시스템이 변경되거나 프로그래머들이 깜빡하거나 팀에 새로운 사람들이 추가될 때 불변속성이 유효한 상태로 유지되기란 거의 불가능합니다.

변수를 명시적으로 체크해서 불변속성을 제거함으로써 유지보수성을 향상시킬 수 있습니다. 그러나 이렇게 하면 리팩터링 해서는 안되는, 코드가 수행하는 작업이 변경됩니다. 대신 이런 경우 리팩터링은 불변속성을 더욱 쉽게 볼 수 있도록 서로 가깝게 이동시켜 유지보수성을 향상시킵니다. 이를 가리켜 '함께 변하는 것은 함께 있어야 한다'는 의미의 불변속성의 범위제한(localizing invariants)이라고 합니다.

값을 입력하면 리팩터링 전과 후에 동일한 결과를 얻어야 합니다. 결과가 예외인 경우도 마찬가지입니다. 한가지 주목할만한 예외는 성능을 바꿀 수 있다는 것입니다. 특히, 리팩터링 중에는 코드가 느려져도 거의 신경쓰지 않습니다. 여기엔 여러가지 이유가 있습니다.
첫째, 대부분의 시스템에서 성능가독성유지보수성보다 가치가 떨어집니다.
둘째, 성능이 중요한 경우 프로파일링 도구나 성능 전문가의 지도를 받아 리팩터링과 다른 단계에서 처리해야 합니다.

그들은 '상속보다는 컴포지션(composition)을 사용하라'고 말하며, 그것을 피하는 방법도 알려주었습니다. 이 조언이 이 책의 핵심인데, 우리가 설명하는 대부분의 리팩터링 패턴과 규칙은 구체적으로 객체 컴포지션을 돕기 위한 것들입니다. 즉, 객체가 내부에 다른 객체의 참조를 가지는 것입니다.

컴포지션의 가장 큰 장점은 추가(addition)를 통해서 변경이 가능하다는 것입니다. 이것은 기존 기능에 영향을 주지 않고 기능을 추가하거나 변경할 수 있음을 의미하는데, 어떤 경우에는 기존 코드를 변경하지 않고도 가능합니다. 이 속성을 개방-폐쇄(open-closed) 원칙이라고 하는데, 소프트웨어 구성 요소들은 확장에 대해 열려있어야 하고, 수정에 대해 닫혀 있어야 한다는 의미입니다.

다른 코드를 건들지 않고 변경할 수 있다면 그 모든 시간을 아낄 수 있습니다. 물론 계속해서 코드를 추가하면 코드베이스가 빠르게 늘어나는데, 이것이 문제가 될 수 있습니다. 어떤 코드가 사용되고 어떤 코드가 사용되지 않는지 주의를 기울이고 사용하지 않는 코드는 최대한 빨리 삭제해야 합니다.

코드를 리팩터링하지 않고 그냥 전달하기만 하면 다른 프로그래머의 시간을 빼앗는 셈입니다. 설상가상으로 지금까지 설명한 부정적인 요인들로 인해 열약한 소프트웨어 아키텍처에 대한 이자가 붙습니다. 이를 기술 부채(technical debt)라고 합니다.

리팩터링은 종종 새로운 팀 구성원을 위한 입문용 작업으로 자주 사용돼서 팀원들이 고객을 바로 상대하지 않고도 안전한 환경에서 코드를 활용해 학습할 수 있습니다.

profile
적당히 잘하고 싶어요

0개의 댓글