포스트

금융권 코드는 클린할 것 같았어요.

금융권 코드는 클린할 것 같았어요.

교육생들과 얘기하는 것은 종종 신선한 경험이 되기도 한다. 이번에도 그런 일이 있었다.
금융권 취업에 관심이 있는 교육생이 면담을 신청했다. 자연스럽게 “왜 금융권에 관심이 있나요?”라고 물어봤다. “금융권은 코드가 클린할 것 같아서요.” 그리고 흔들리는 나의 동공.. 다음으로 한 시간 가까이 금융권의 코드가 클린하기 어려운 이유를 설명했다. 잘 전달됐을까..

15년 가까이 금융 시스템을 개발하며 많은 코드를 보고 고치고 써왔다. 그 중에 “클린”한 것은 아주 드물었다. 한 마디로 표현하면 복잡한 문제를 그냥 복잡하게 풀었다고 할 수 있다. 클린하지 못한 솔루션.. 왜일까? 몇 가지 원인을 생각해봤다.

금융권 코드가 클린하기 어려운 이유

  1. 금융이란 원래 복잡하다.
    금융은 물리 법칙이나 기계의 규칙이 아닌 인간의 규칙으로 되어 있다. 기계의 규칙은 한계가 명확하다. 되는 건 되는거고 안 되는건 안되는 거다. 인간의 규칙은 한 마디로 제멋대로다. 어느날 갑자기 바뀐다. 세법은 매년 개정된다. 회계 규칙은 내가 있는 동안 한 번 크게 바뀌었고(K-IFRS) 이후로도 소소하게 바뀌고 있다. 그외에도 수 많은 것들이 예상하기 어려운 방향으로 바뀐다. 대략 생각나는 것만 해도 도로명 주소, 차량 번호판 3자리, 개인정보관련(파기, 조회 권한, ..) 등등 너무나 많다. 게다가 대부분 사람말로 되어 있어서 모호할 때도 있다. 그러면 관계자들을 불러다놓고 설명회를 하고 질의를 하며 규칙을 다듬어간다. 그러는 사이 시간은 흘러 시행일이 다가온다. 요구사항은 아직 개발할 수 없는 상태인데.. 이런 상황에 클린 코드가 나오려면 기적이 필요하다.
  2. 금융 시스템도 복잡하다.
    거래 하나가 흘러가는 것도 복잡하다. 인뱅에서 이체 하나만 눌러도 이 정보가 거쳐가는 곳은 상당히 많다. 거래를 처리하기 위해 필요한 정보도 상당히 많다. 계좌가 동결되지는 않았는지, 금감원 신고 대상 거래인지, 이상거래는 아닌지 등등 체크해야 할 것도 많다. 타행이라면 얘기가 더 복잡해진다. 수신 쪽은 잘 모르지만 생각만 해도 복잡한 게 한둘이 아닐 것 같다. 금융은 상당수가 연결에 관한 것이기 때문이다.
    이 복잡한 걸 하나의 트랜잭션으로 묶어줘야 한다. 되거나 안 되거나. 어딘가에서 실패하면 그걸 복구하기 위한 코드가 또 달라붙는다. 실패할 포인트는 너무나 많은데..
    개념상으로는 이렇게 쉬운 게 없다. 이 계좌에서 금액 빼고 다른 계좌에 그만큼 더해주면 되는 것이다(아 잠깐 그래도 거래내역은 쌓아야지). 그걸 간단한 걸 하기 위해 수 천줄, 수 만줄의 코드가 실행된다. 질소포장 과자같다고 할까? 알맹이는 요만큼이고 감싸는 게 대부분이다.
  3. 조직도 크고 복잡하다.
    금융사들은 보통 크다. 당연히 조직도 다양하게 나뉘어져 있고 복잡하게 얽혀있다. 그게 시스템에 반영된다. 각 조직에서 관리하는 시스템도 따로 나뉘어져 있다. 그 조직의 관심사, 역학, 이해관계 등이 반영된 무언가가 탄생한다. 그 친구도 이제 시스템의 한 구성원이 된다. 콘웨이의 법칙이랄까? 그런 것이 작동한다.
  4. 차세대와 외주 관행
    금융권 시스템은 대규모/외주 개발 후 오랜 유지보수 기간을 가진다. 외주 개발은 데드라인이 명확하다. 시스템을 충분히 이해하고 개선할 여유가 없다. 빅뱅으로 대규모 개발을 한 뒤에 운영에 핸드오프 한 뒤 떠난다. 그리고 기다리는 것은 수 많은 변경사항들.. 긴 유지보수 기간 동안 그것들이 코드에 쌓이고 쌓인다.
  5. 조직 문화
    조직 문화도 한 몫 거든다. 우선 안정지향. 장애나 오류가 나면 금전 손실이 발생할 수 있고 이건 신뢰를 바탕으로 작동하는 금융에 있어서 큰 타격이 될 수 있다. 그래서 혁신과 개선 보다는 안전을 택하게 된다. 그리고 변경건은 책임자의 결재를 거친다. 책임자는 시니어들이고 그들은 COBOL로 대표되는 절차지향 프로그래밍에 익숙한 사람들이다. 깔끔하게 함수로 역할이 분리된 코드 보다는 수천줄 짜리 프로시저가 편하다.

주니어 때 부터 많이 듣던 말 중에 하나가 “누구나 읽을 수 있게 짜라”는 거였다. 근데 이건 가독성 얘기가 아니었다. 직관적으로 짜라는 뜻이었다. 요구사항이 if/else로 되어 있다면 그대로 하라는 것이다. 전략 패턴이나 템플릿이 잘 맞아 보이더라도 그런 추상화를 적용하기 힘들다. 추상화는 항상 가정을 동반하고 그 가정이 언제 깨질지 모르기 때문이다. 그냥 쉬운 어휘로 작성하는 게 운영을 위해 나은 선택이 된다.

이 모든 것들이 코드베이스에 영향을 미친다. 결과는..?

근데 그게 잘못된 것일까?

물론 더 좋은 코드 안에서 일하면 좋을 것이다. 누구나 그렇다. XP 였는지 실용주의 프로그래머였는지 객체지향으로 금융 시스템을 개발하는 얘기를 읽은 적이 있다. 내 생각은.. 저게 정말 될까? 내가 매일 만나는 코드는 이모냥인데..

근데 이 글을 써내려가며 내린 결론이 있다. “클린하지 못한 건 나쁜 게 아니다. 그게 시스템이 세상을 배운 흔적이다.” 장애, 잘못된 가정으로 인한 결함, 예상치 못한 변경을 거치며 처음의 깔끔하고 순수한 모습은 어딘가로 사라지고 여기저기 상처와 흉터, 땜질이 가득한 그것이 바로 시스템이 살아오고 버텨온 흔적을 보여주는 것이라는 생각이 들었다.

흉터가 없는 몸은 아직 밖에 나가보지 않은 몸이다. 그 if 분기 하나하나가 “이런 일이 실제로 일어났다”는 기록이고, 땜질 하나가 “이걸 몰랐는데 알게 됐다”는 학습의 흔적이다. 오히려 의심스러운 건 너무 깔끔한 코드다. 아직 충분히 현실을 만나지 않았거나, 복잡성을 다른 곳으로 안 보이게 치워놨을 뿐인 경우가 많다.

물론 이게 지저분한 코드에 대한 면죄부가 되어서는 안 된다. 원래부터 부실한 뼈대와 흉터는 다르기 때문이다. 전투에서 생긴 상처와 체력 관리를 안 한 건 다른 문제다. 금감원 지침이 갑자기 바뀌어서 급하게 분기를 추가한 것과, 처음부터 변수명을 a, b, c로 쓰고 함수 하나에 1000줄을 넣은 건 전혀 다른 이야기다(쓰고 보니 내 얘긴가..). 내가 통제할 수 있는 복잡성과 통제할 수 없는 복잡성을 구분하는 눈은 여전히 필요하다.
다만, 현실의 코드가 왜 그런 모습인지를 이해하는 것과 모르는 것 사이에는 꽤 큰 차이가 있다고 생각한다.

오늘도 흙투성이 코드 속에서 고군분투하고 있을 금융권 개발자들, 화이팅.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.