오늘 드디어 C++의 mutable 키워드를 살짝 이해한 것 같아서 적는다.

C++ 개발자 경력을 쌓은지 이제 3년째.

C++의 mutable 키워드를 처음 알게된 것은 입사 후 팀장님과 effective C++책을 공부할 때였다.

그 전까지는 mutable 키워드가 있는지도 몰랐다.

effective C++ 책의 초반부의 2장 3장 4장에는 const에 대한 소개와 객체지향설계에서의 const의 효용이 주를 잇는다.

이 부분을 한 문장으로 요약하면

const를 일단 붙이고보자!

이다. 그리고 이 장을 공부하면서 팀장님이 강조하셨던 부분은 const_cast를 쓰지마라였다.

역시나 이때는 const_cast도 뭐하는 녀석인지 하나도 몰랐다.

const_cast는 한 마디로 const 키워드가 붙어 상수화된 변수 또는 개체의 상수성을 제거하는 것이다.

이걸 쓰면 안되는 이유는 const의 목적과 위배되기 때문이다.

const를 붙이는 이유는 보통 개발자가 고려하지 않은 외부 참조에 의한 값 변경을 방지하기 위해서이다.

그런데 const_cast를 통해서 이렇게 const 상수성을 무시하고 값 변경을 하다보면 보이지 않는 버그가 자라난다.

이건 지난 2년 반 동안 무척 많이 겪었다. (side-effect가 장난아니다.)

그럼에도 const_cast에 손이 가는 이유는 마감은 임박하는데 const로 인해서 계속된 컴파일 오류가 발생하면 그냥 const를 무시하고 const_cast를 써서 쉽게 가고 싶은 욕구가 든다.

하지만 이런 방식은 결국 기술적 채무로 다가온다.

처음 선배들이 한 const에 대한 고심끝에 설계한 클래스 또는 구조를 내가 망치는 셈이다. 조심하자.

그리고 컴파일에서 오류를 걸러주는 것은 무척이나 행복한 일이다.

런타임에서 서비스 후 문제가 발생하는 것은 끔찍하다. 차라리 손쉽게 해결할 수 있는 컴파일 오류가 좋다.

이런 const를 책에서는 이렇게 표현한다.

'팔방미인'이라고.

그만큼 객체지향설계에서 const 키워드가 가진 힘은 대단하다고 한다.

이 책에 영향받아 나도 const에 무척 좋은 인상을 가졌고 잘 쓰고싶은데 ... 사실 잘 안된다.

아무튼 이번 주제는 const가 아닌 mutable이므로 mutable에 대해 쓰자면 처음 mutable에 대해 이해가 어려웠던 것은 책에서 나오는 다음과 같은 말 때문이었다.

'mutable키워드는 비정적 데이터 멤버를 비트수준 상수성의 족쇄에서 풀어 주는 아름다운 오색약수같은 키워드입니다.'

지금 다시봐도 이게 뭔 말인지 다 이해는 안간다.

비트수준 상수성이라니. (책에서 비트수준의 상수성에 대해 소개한다. effective C++ 64 page, 2번째 줄) 

지금도 이럴진데 객체지향 개념도 거의없던 신입 시절의 내가 이를 이해하는 것은 솔직히 어려웠다.

그래서 더 mutable에 대해서 기피하게되었고 혹시나 코드 안에 mutable이 있으면 그 이미지로 인해서 코드가 확 어렵게 다가왔다.

그런데 오늘 드디어 mutable이 마음에 다가왔다.

그 시작은 바로 상수 객체에 대한 이슈로 인해서다.

mutable은 상수 객체안에 해당 키워드가 작성된 멤버에 한해서 상수 객체임에도 해당 멤버는 변경될 수 있음을 컴파일러에게 알리는 키워드다.

내가 본 클래스는 클립보드의 데이터를 구현한 객체인데 (클립보드는 우리가 메모장에서 ctrl+c 한 내용을 포털에서도 crtrl+v로 붙여넣기 할 수 있게 해주는 운영체제 내부의 복사 개체를 저장해두는 보드를 일컫는 개념이다. 꼭 메모장<->포털이 아니더라도 각각의 독립적인 프로그램이나 App들이 하나의 복사한 객체를 공유할 수 있게 하는 기술.)

클립보드 데이터는 복사한 순간부터 다른 외부 조건에 의해 내부 정보가 변하면 안되므로 모든 클래스의 멤버 및 함수가 const가 붙어있는 상수 객체로 설계되었다.

이 클래스의 작성 시점은 2009년이었다.

이 때만해도 이 클립보드 상수 객체는 완전한 설계였을텐데, 지금 2019년에 클립보드 관련된 새로운 기능이 추가되면서 이 상수성을 해결해야했다.

이 완전 상수화된 클립보드 데이터 클래스는 base class로서 존재했고 현재는 약 8개의 클래스가 상속받아서 각자의 필요한 부분이 작성되도록 코드가 짜여져있었는데 나는 이 8개의 클래스 중 약 3개의 클래스에 새로운 기능을 추가해야 했다.

이 새로운 기능은 클립보드 데이터 클래스로 하여금 유저가 선택한 정보를 가지도록 구현되어야 했다.

이 유저가 선택한 정보는 App 실행중에도 언제든지 변할 수 있어야 했으므로 상수 객체와는 어울리지 않았다.

초기 설계를 지키기 위해서는 이 유저 선택에 따라 변하는 값을 외부에 저장하도록 하고 구조를 변경해야 했지만

그렇게되면 또 코드 응집성이 떨어져서 나중에 문제가 될 것 같기도하고 또한 이 클래스의 코드는 정리된지 오래 지나서 잠깐 사이에 구조 변경을 할 수 있지 않았다. (당장 내일까지 해결해야 하는 문제였다.)

그 때 mutable 키워드를 사용한 선배의 코드가 보였다.

컴파일 오류도 해결하고

관리하기 어렵게 외부에 데이터를 둘 필요도 없고

const의 기본적인 존재 이유인 개발자가 의도하지 않은 멤버 변수의 변경이 아닌 개발자가 의도한 멤버 변수의 변경으로

만들어 주는 mutable 키워드가 갑자기 이뻐보였다.

물론 아무리 개발자의 의도라고해도 남발하면 const_cast처럼 어느덧 객체의 상수성을 깨트릴 확률이 크겠지만

알고 적절히 주석을 달고 조화롭게 사용한다면 저자가 왜 오색약수라고 표현했는지 알 것 같은 쓰임이었다.

물론 책에 따르면 무조건적인 상수성을 지향하는 비트수준 상수성 (물리적 상수성)

몇몇 비트는 변경을 허용한다는 논리적 상수성 (지금같은 mutable 키워드)

두 상수성 사용에 대한 논쟁은 많이 있다고 한다.

이 부분은 C++ 거장들의 철학 논쟁과도 같으니 아직 새내기인 나로서는 mutable을 잘 사용해봤다는 것에 의의를 두자.

끝.

1년만에 글을 쓴다.

그동안 여러 일들을 겪으면서 글을 쓰는것을 포기했는데 역시나 글을 쓰는게 좋다.

오랜만에 글을 쓸 때는 역시 쓰고싶은 것을 쓰는게 좋을 것 같아서 평소 생각했던 주제에 대해서 쓴다.

전공 지식도 아니고 그냥 소설같은 주제다.

일을 하는데 문득 메모리에 대해서 생각이 났다.

메모리.

일을 하다보면 잊고 살지만 잊고 살면 안되는 것.

C++ 개발자지만 어느덧 익숙해진 C#과 C++의 스마트포인터, 그리고 선배들이 이미 만들어둔 클래스를 사용하면서 잊고 있었지만, 오늘 메모리 누수 이슈를 찾아보면서 다시 한 번 생각해봤다.

프로그램을 짜다보면 나같은 경우엔 프로그램이 굉장히 복잡하게 여겨진다.

학부생일 때도 복잡하다고 생각했지만 실무에서는 겪어보지 못했던 각종 매크로들과 거대한 규모의 코드량과 복잡하게 섞인 디자인패턴 등으로 인해서 프로그램이란 것은 생각했던 것보다 훨씬 더 복잡하다고 생각했다.

그런데 가끔씩 프로그램의 본질이 메모리라는 것을 알게되면 손쉽게 해결되는 버그들이 있었다.

그럴때면 왜 내가 이렇게 복잡하게 생각했을까? 라고 문득 의문이 든다.

대학교 때 Context Switching이란것을 배웠다.

컴퓨터 구조 수업때 배운 개념이었는데 그 당시엔 제대로 알지도 못하고 머릿속에 집어넣기 급급했다.

그런데 이 개념은 취업준비생일 때 각종 시험 문제로 많이 등장했었다.

각각의 프로세스들이 프로세스 스케쥴링에 의해서 할당된 시간만큼 메모리를 점유해서 사용하는 것을 의미한다.

학부생일땐 그때는 그냥 그렇구나하고 생각했고, 취업준비생일때도 중요하다고 생각했지만 단지 시험문제로 많이 봐서 중요하다고 생각했을 뿐이었다.

그런데 지금은 뭐랄까? 메모리는 뭔가 우리 세계의 땅과 닮았다.

이게 뭔 문학적인 생각일지는 모르겠지만 어느날 문득 메모리 위에 올라간 프로그램을 보면서 생명을 얻은것처럼 보였다.

왜냐하면 메모리가 터져버린 프로그램을 곧바로 종료된다.

아주 정교한 놈이라서 조금만 잘못된 메모리 주소를 참조하면 그대로 프로그램을 강제종료가 발생한다.

보통 이럴 때 '어.. 죽었다!' 이렇게 말하곤 했는데

생명이 존재해야 죽음도 있으니 문득 이렇게 생각한 순간부터 메모리에 올라간 프로그램은 생명을 가진 것처럼 보였다.

그러니 이전에 그냥 별 생각없었던 Context Switching도 뭔가 생명을 잉태시키는 요람같은 개념으로 보인다.

그리고 게임도 그렇다.

'엘더스크롤'같은 거대한 RPG 게임을 하다보면 가끔씩 이런 세계를 구현한 이 게임 프로그램이 너무 대단한게 느껴진다.

보통 CPU 속도를 표현할 때 hz단위를 쓴다. 그냥 한국말로 표현하면 4기가 헤르츠 이렇게 말하곤하는데

1헤르츠는 내가 대학교 교수님한테 들었던 수업에서는 어떤 광물에 빛을 쪼였을 때 나타나는 파동의 단위라고했다.

그러니까 1헤르츠는 보통 컴퓨터 프로그램에서 1틱을 나타내는데 이 1틱은 하나의 연산을 할 수 있다.

이 연산도 우리가 흔히 프로그램 언어(고급 언어)에서 쓰는 연산이 아니라 전자 회로의 가장 기본이되는 연산 회로

AND회로, OR회로, XOR회로 등 하나의 회로를 지나는 연산을 의미한다고 한다.

아무튼 이런 1헤르츠는 이런 연산을 하는 단위라고 생각하면 흔히 4기가 헤르츠는 1초당 4000,000,000번의 연산을 할 수 있다는 소리가 된다.

그리고 이런 엄청난 연산을 통해 잘 짜여진 그래픽 및 내부 엔진 프로그램이 메모리 위해서 구현되고 하나의 게임 세상을 표현한다.

지금 내가 뭘 쓰고있는지는 모르겠는데 음 그러니깐 말하고 싶은 것은 이런 것 같다.

어떤 거대한 시스템도 하나의 세계를 표현한 RPG 게임도 결국 메모리에 올라가야 그 모습을 드러낼 수 있다.

프로그램의 본질은 메모리라는 것.

그리고 이 메모리위에 짜여진 수많은 연산들이 게임이란 현실과 비슷한 세상을 구현한다는 것.

메모리 2d라면 뭐랄까 우리 세상이 4d 기반의 메모리 위에서 구현된 세상같다? 우주가 생긴것도 어두컴컴한게 현실 세계의 메모리같기도 하고...

아 빵터졌다. 갑자기 SF 소설을 쓰고있다.

아무튼 결론은 음 메모리 누수가 났는데 앞으로 메모리 누수가 안나도록 프로그램을 잘 짜도록 하자!

아무리 복잡해보이는 프로그램도 본질은 메모리위에서 돌아간다.

어셈블리어를 유창하게 읽거나 Reversing을 할 수 있다는 것은 이런 프로그램의 이해해 엄청난 도움이 될 것 같다.

학부 때 어셈블리어 수업 D+맞았던 것 같은데 좀 열심히 할 걸 후회된다.

그랬다면 내 능력은 한층 더 발전했을 수도 있었을텐데.

그러니 너무 복잡한 나머지 나 혼자 생각에 매몰되 피하지말고 천천히 하나씩 분석해서 찾다보면 많은 문제가 길이 보이지 않을까. 그냥 그런 생각에 글을 썼다.

끝.


주 52시간 근무가 시작되고 야근이 사라졌다.

또한 공짜로 먹던 저녁 식사도 함께 사라졌다.


슬프다.


이젠 저녁 식비로

올해 올랐던 연봉만큼 빠져나갈 것 같다.


하지만 시간이 많이 생겼다.

그리고

이렇게 공부를 하러왔다.


AI 공부인데

여전히 이해가 하나도 안되지만

정말 만들어보고 싶은걸 만들 수 있는 그날까지 계속 하고싶다.


노트북으로 학습을 시켜두고

그동안 이렇게 글을 쓴다.



신입 사원 교육을 들을 때다.

객체지향적 사고를 위한 교육을 듣던 중이다.


객체지향의 주요한 특징들

추상화

상속

다형성

(캡슐화는 제외)


이 3가지 속성에 대해서 열띤 교육을 들을 때다.


각각의 개념을 들을 때마다

절로

고개가 끄덕여지는 강의들이었다.


팀장님, 이사님, 선배님들의

각자의 경험들을 살린 교육을 듣고있으면

마치 내가 객체지향의 프로가 된 기분이었다.


그러다 나온 질문이 하나있다.

'너는 객체지향에서 가장 중요하다고 생각하는게 뭐야?'


정답이 없는 질문


더 중요하고 덜 중요하고 이런건 없다.

다 중요하다.


그래도 신입인 입장에서 질문을 받았으면 답변하는게 도리이니

곰곰히 생각하다가

나는 추상화라고 말했다.


왜냐하면

상속이나 다형성은

뭔가 어렴풋이 이런 개념이 나온 이유도 이해가 되고

어떻게 하는지도 머리속에 명확하고

코드로도 조금은 그려져서

그래서 가장 이해가 안되는 추상화라고 답했다.


함께였던 다른 동기들의 답변들은 다양했다.

가장 많은 답변은 다형성이었던 것 같다.


추상화

아니 추상이란 단어의 의미


설계학적으로는 인터페이스와 구현을 분리한다고 하지만

난 이 말이 너무 어려웠다.


진짜 그냥 생각해보면 아무것도 아닌데

막상 추상화시켜서 클래스를 작성한다고 해보면

뭘 어떻게 하라는건지 감이 안왔다.


또 일상 생활에서 많이 쓰던 인터페이스란 뜻조차

어느 순간부터는 헷갈리기 시작했다.

내가 인지하고 있던게 맞는건지, 헤매던 시간


나에게 이 말을 철학과 같았다.

그 때 속마음이


'뭐 느낌은 알겠는데

근데 어떻게 하는걸까?'


'그렇게해서 진짜 도움되는건 뭐고

실제로 코드로는 어떻게 표현하는데?'


인터페이스와 구현을 나누었을 때

명확한 이점이 나한테는 보이지 않아서 더욱 이해가 안갔다.


그리고

이제는 조금은 추상화라는게 이해가 간다.

선배들이 짰던 코드들과 이후에 디자인패턴 쪽을 공부하면서 야금야금 정립이 되던 시간들

그리고 코드로도 어떻게 표현하는지.


이에 관련된 건 제대로 포스팅하고 싶어서 다음으로 미루고


이번 포스트의 핵심 주제인 이름 잘 짓기.


그래 이거였지.


위에서 주저리 주저리 객체지향개념을 꺼낸 이유가 바로 이걸 쓰기 위해서다.


객체지향에서 가장 중요한건 3대 개념이고 뭐고

캡슐화고 뭐고

은닉화고 뭐고

추상화고 뭐고

상속이고 뭐고

다형성이고 뭐고


제일 중요한 것은 함수 및 변수 이름을 잘 짓는게 가장 중요하든 것이다.


객체지향을 떠나서 그 어떤 코드를 짤 때

이름 짓는 일에 시간을 소홀히 하면 안된다.


급해서 넘어갔다고 해도 다시 돌아와서 마음에 드는 이름으로 바꿔야한다.


이름 짓기의 가장 중요한 것

!! 명확함 !!


찾아보면 Microsoft가 지정한 학습 도서인  'Code Complete'을 보면

이름 짓는 몇몇 규칙을 알려준다.


나보다 훨씬 뛰어난 프로그래머 분들의 말씀이니 정말 새겨들어야 한다.

가장 이상적인 이름의 길이

변수 및 함수에서 자주 쓰이는 단어들


막 엄청 많다.


근데 내가 느낀건

길이는 중요하지 않다.


각 회사나 팀의 이름 짓기 Convention(규칙)이 있다면

그 Convention을 아주 충실히 따르는 전제하에

이름은

언제나

한 눈에

알아보기

쉬워야한다.


궁극적으로는

주석없이도

이게

어떻게

돌아가는 코드인지

그 코드의

변수 이름과

함수 이름과

클래스 이름을

통해서


그런 코드를 짜야한다.


일전에 교수님의 말씀 중에 남는 말이 있다.

교수님은 빅데이터 교수님이셨고 남편 분은 현업 프로그래머셨는데

집에서 언제나

변수 이름 하나를 짓는데

30분 이상을 고민한다고 하신다.


그리고 코드 짤 때 가장 어려운게

이름 짓는 일이라고 한다.


공감이 매우 간다.


이름 잘 지어야 한다.

특히

오래된 프로그램일수록

오래갈 프로그램일수록


후에 어떤 사람이 내가 짠 코드를 볼 지 모르는데

개인만의 이름이나 규칙은

가져다버린후

훗날

스스로가 세계에서 인정받는 개발자가 되면

그 때 상징적 의미로 가져오도록 하자


가장 최악의 이름 3개


1번

for문에서 index의 이름 i, j, k로 짓는 것

나중에 변수 잘못 써서 논리적으로 문제되면 찾기도 어려울 뿐더러

검색도 하기 어려움

위치 찾기도 어려움


2번

연결되는 변수와 함수의 이름을 구분지을 때

뒤에 1, 2로 숫자로 네이밍하는 것

이름은 언제나 무엇을 하는지 명확해야 함


이상적인 것은 주석없이 읽을 수 있는 코드가 이상적인데

이상적인 것은 이상적인 것이고

쪼렙땐 최대한 주석 상세하게 적기


더 좋은것은

코드 짜기전에 먼저 주석으로 동작해야 할 일을 써놓고

코드를 작성하면 좋다.

습관적으로 잘 안되서 문제지만.


3번

짧은 이름

책들을 보면

이상적인 이름 글자 수를 정해놓거나

단어 수를 정해놓거나 그렇다.

그런데 막상 짓다보면 이상적인 이름을 짓는건 정말 어렵다.

뭔가

머릿속에

딱~!

이거닷~!

하고 떠올라도

오래되고 규모가 큰 프로그램이면 비슷한 느낌의 이름일 가능성이 매우 매우 높다.


아무리 좋은 이름이어도 다른 변수나 함수와 의미가 혼동되게 되면

그것은 안좋은 이름이다.


그렇다고 귀찮다고 완전 의미가 없는 이름을 지으면

그건 진짜 최악.


짧게 짓느니 엄청 엄청나게 길어도 의미가 명확한 이름이 낫다.

짧게 짓느니 엄청 엄청나게 길어도 의미가 명확한 이름이 낫다.

짧게 짓느니 엄청 엄청나게 길어도 의미가 명확한 이름이 낫다.



-끝-


-------------------------------------------2019.09.07-------------------------------------------

변수 함수 이름에 대해서 추가.


위 내용에 대한 결론은 이름을 잘 짓자.

그리고 짧은 이름보다 길어도 명확한 이름이 낫다.

라는 결론이었다.


이 포스트를 쓰고 1년쯤 지났다.

그동안 위에 적은대로 명확한 이름을 짓기위해 노력했다.

그러면서 겪은 시행 착오들을 추가한다.


1. 이미 선배들이 지은 이름이 굉장히 축약된 이름일 경우

...

솔직히 굉장히 난감하다.

아무리 수평적인 개발자 문화라지만 눈치가 보인다.

바꾸고 싶은 마음은 굴뚝같은데 여기서 문제.


내가 지은 이름이 상대방에게도 좋은 이름이라고 단언할 수 없다.


왜냐하면 그 분은 이미 이 이름에 익숙해져있기 때문에 오히려 새로 바꿀 내 이름이 정말 좋은가?

생각하게 된다.

나에게는 좋다. 그러나 상대방에게는 새로 적응해야한다.


두 번째.

열정에 불타서 이름을 열심히 바꿨다.

내심 만족했다.

이름은 대규모 프로젝트의 경우 한 번 잘못바꾸면 엄청난 규모의 코드를 바꿔야한다.

스마트하게 VisualStudio의 전체 바꾸기를 하면 좋은데

물론 내가 Side-Effect를 커버할 수 있는 범위라면 그렇게 해도 좋긴한데

10년 이상 유지보수해온 코드이므로 당연히 자동으로 테스트하는 기법이 적용되어 있지 않다. 우리 프로젝트는.

테스트케이스도 없으므로 Side-Effect 검출은 순전 고치는 사람의 능력과 책임이다.

또한 한 소리 들었다.

마일스톤이 다가오는데 왜 시간을 이슈 해결이 아닌 다른쪽에 쏟느냐.

이렇게 고쳤을 때 Side-Effect는 예상이 가느냐.


최고의 해결법.

VisualStudio의 정규식을 활용해서 모두 바꾸기하자. (그럼에도 놓치는 부분들이 있다.)

정규식을 사용하지 않으면 무서워서 바꿀 수 있음에도 Side-Effect가 무서워 안하게되거나

순수 노가다를 해야하므로 굉장히 바보스런 일이다.

그렇다고 정규식을 생활화하자.

내 실력에도 도움이 된다.


요즘들어 항상 인정도 못받는거 굳이 이렇게 이름을 고쳐야하나?

라는 생각이 들었다.

가졌던 강박들이 좀 깨지는 느낌도 들고.


그러던 와중에 하나의 기능이 내 담당이 되었다.

이 기능또한 약 10년동안 유지보수해온 기능이며

여러 담당자의 손길이 거쳐갔다.

처음 이 기능의 담당자가 되었을 때 완전 멘붕이었다.


왜냐하면 이 기능의 이름이 3가지 정도로 흩어져서 구현되어있었는데

코드 이해하기가 정말 dirty하게 어려웠다.

kinsoku, forbiddenCharacter, turnoverWord

이렇게 3개인데 뜻은 '금지문자'라는 의미이다.

그래서 팀장님과 합의하고 차후 담당자를 위해서 이 이름을 통일해야한다고 설득해서 고칠 시간을 벌었다.


그리고 한 6개월 후에 다시 관련 이슈가 생겨서 버그 트래킹을 하는데

정말

편했다.


그러니 이름을 바꿔야할 때는 반드시 바꾸자.

그리고 가장 중요한 것.

반드시 팀장님과 합의하에 바꾸자.

그냥하면 인정도 못받고 일하는 시간에 딴짓하는걸로 보인다.

끝.

입사해서 가장 많이 듣은 말.


코드를 짤 때 절대 중복코드를 쓰지마라.


그리고 얼추 2년이 다 되가는 지금 난 다시 아니 여전히 중복코드를 쓰고있다.


중복코드를 쓰게되는 이유


1번

시간이 없다.

오늘 안에 처리해야 할 건 많은데

코드 품질을 생각하며 코드를 작성하기에는

아직 신입 열정에 가득찰 땐

이런 것 하나하나 따져가면서

선배들에게 묻곤했다.


중복되는 것 같으니

이렇게 하나로 빼서 쓰면 안될까요?


지금은

질문이 없다.


내 멋대로, 나 편한대로

빠르게 처리할 수 있는 방법으로 점점 빠져든다.


예전에는

조금 느리더라도

코드 구조나 변수 이름들이 내 마음에 들 때까지 고민하고 고민했다.

그로인해서 야근하게 되더라도.


지금은

퇴근 시간이 되면 도망가기 바쁘다.


이렇게 일 끝나고 카페에 앉아서

공부하는 것도 오랜만이다.

너무 행복한데, 맨날 잊고산다.


아무튼 다시 본론으로 들어와서

중복코드를 쓰지마라

라는 단순하지만 뭐가 뭔지 모르겠는 이 말.


그래서 순전히 내가 겪은 것만 쓴다.

중복코드를 쓰는 순간, 버그가 발생 확률이 대폭 상승한다.


근거 1

개발은 나만 하지 않는다.

언젠가 나의 코드를 그대로 사용하는 사람도

내가 만든 함수나 메서드를 사용하는 사람이 생긴다.


시작은 하나의 중복코드였지만

점점 사용되는 곳이 많을 수록

나도 모르게 겉잡을 수 없이 불이 번져있다.


그렇게 나도 모르게 증가하는 중복코드들.

단순하게 제거하자고 마음먹으면 쉽다.

쉬울 것 같다.

그런데 어렵다.


1번

가끔씩 구조가 엉켜서 빼기가 중복코드를 어려운 부분이 있다.

2번

이미 검증이 완료됐는데 구조를 바꾸는 것은 최소 야근 각오하고 해야한다.

3번

코드는 멈춰있지 않고 계속 변한다.

언젠가 이 중복코드를 고쳐야한다면

여러 군데 다 퍼져있는 중복코드를 고치는 건 어마어마한 일이 되버린다.


단순히 모두 수정 기능으로 해결안되는 부분이 투성이다.


테스트케이스를 잘 작성해둔 코드나

유닛테스트가 잘된 코드라면 그래도 괜찮겠지만


그런게 없다면

수정했을 때 버그가 없다고 아무도 확신해주지 않는다.

그러므로 내가 하나하나 다 확인해야 한다.


신입때는 확실하게 하기 위해서 다했다.

배운 것을 쓰고 싶은 욕심도 있었고

이런 것을 하면서 코드 품질에 기여하고 있다는 생각을 했다.


그런데 점점 귀찮다.

일을 쌓여만 가고

모르는 것은 아직 투성이고

외적인 일들로 일에 집중에 안되는 요즘같은 날이면


그리고 또 문제

중복코드는 어쩔 수 없이 코드 크기를 증가시킨다.


난 대학생 때 하나의 함수가 최소 50줄 최악은 100줄은 안넘을지 알았다.


그런데 아니다.


하나의 함수가 3천줄짜리 함수가 존재한다.

그것도 너무 중요한 부분에.


잘못고쳤다가는 난리날까봐 건드리기가 너무 무서운 부분이다.

언젠간 고쳐야겠지.


이젠 내 업무가 됐으니까.

하지만 엄두란게 생길 때가 언젤까?


내가 이 회사를 떠나기 전에 오긴 할까?


아무튼 셀 수 없는 매크로와 중복코드의 연합은

컴파일 시간, 바이너리 크기에도 영향을 준다.


처음엔 끽해야 얼마나 영향을 주려고 생각했다.

하지만

10년 이상 크기가 커져온 대형 프로그램에서

현재 안드로이드에서 풀빌드하는데 걸리는 시간은 5시간이며

윈도우에서는 2시간이다.


그러다 빌드 실패하면 반나절이 사라진다.


나 오늘 뭐했니...?


이런 날은 눈치가 보여서라도 강제 야근이다.


또한 중복코드를 없애는 것도 일이다.

기존에 존재하는 수없이 많은 중복코드들

배운대로 열심히 없앤다.


하나로 통합하고, 클래스를 만들어 관리하고, 유틸 함수로 바꾸어 하나로 쓰도록 한다.

음 그런데

때로는 코드 구조 결함 또는 특정 이유를 위해서

중복코드로 작성하는 경우가 있다.


이를 모르고 내 멋대로 잘못 고쳤다가

코드 리뷰 단계에서 이를 선배님들이 잘 캐치해준다면

다행이지만

아무일 없이 지나갔다가

나중에 갑자기 잘되던 기능이 안된다고 연락올 때

그리고 로그를 뒤져보니 내 잘못으로 나올 때

머리 속은 화이트아웃이다.


그리고 또 중복코드를 생성하지마라.

이게 기준이 굉장히 애매하다.

그래 중복코드 안짜는게 중요한 것은 알겠다.


그런데 유닛테스트를 위한 ASSERT() 문들과

아니면 당연한 로직들

생성 후 생성이 잘됐는지 검사하는 구문들


중복코드인지 아닌지 애매한 것들

그런게 많다.

너무 많다.


배운대로 실천하고 싶은데

잘 안 된다.


이게 실력이겠지.


그러므로

기존 것을 수정하여 변화시키는게 아닌

새로운 것을 만들어나갈 때만큼이라도


중복코드를 사용하지 말자!


잊지말고.


귀찮다고 배운대로 안하지말자.

좀 돌아가보면

실력이 늘어있는게 느껴질 때가 오겠지.



+ Recent posts