brunch

You can make anything
by writing

C.S.Lewis

by 백명석 Jul 16. 2023

지속 가능성에 대한 2가지 관점

지속 가능한 서비스와 지속 가능한 개발 방식

나는 지속 가능한 서비스 개발을 하고 싶다는 말을 자주 한다. 지금의 요구사항을 만족시키는 것은 물론 향후 요구사항 변경이 있을 때 빠르고 안정적으로 이를 수용하여 경쟁력을 갖는 서비스를 개발하는 것이 중요하다고 생각하기 때문이다. 대부분의 경력이 서비스 개발 및 운영이었어서 동작하게 만드는 것보다 운영을 하면서 다양한 요구사항을 수용하고, 개선할 수 있는 서비스 개발이 중요하다고 생각하기 때문이다.

지속 가능한 서비스

SW 개발 ‘속도’ 집착이 모든 것을 망치고 있다는 기사에는 여러 가지 주목할 만한 내용이 있지만 나는 2가지가 눈에 띄었다

1. 출시 시기는 실제로 중요하다. 출시 속도가 5% 개선되면 ROI가 13% 증가한다.

2. 미국 노동 통계청에 따르면 소프트웨어 개발자에 대한 수요는 2021년부터 2031년 사이 25% 증가할 전망이다.

개발자에 대한 수요가 늘면서 개발자 부족은 심화되고, 서비스 출시 속도를 높이면 ROI가 개선되지만 출시 이후에 지속적으로 변화하는 요구사항을 빠르게 반영하지 못하면 시장에서 뒤처질 텐데, 대개의 경우 빠르게 구현하여 첫 번째 출시를 빠르게 할 수는 있지만 이후 지속적으로 빠른 출시 속도를 유지하는 것이 매우 어렵다.

SW 변경은 본질 자체

1994년, 스탠디시 그룹

소프트웨어에서 항상 사용되는 부분이 7%, 자주 사용되는 부분이 13%라는 점이 인상적이다. 즉 파레토의 법칙처럼 20%만 사용된다는 것이다. 요구사항을 작성한 사람은 그 요구사항이 구현되어 사용할 수 있어야만 자신이 원한 것이 무엇인지 확신할 수 있다고 한다. 그래서 일정 준수를 위해 개발 시작 전에 요구사항을 확정하자는 말은 참 이상한 말이 된다. 이렇게 개발할 경우 일정 준수는 성공할지 모르지만 80%는 사용되지 않는 코드를 작성할 수 있기 때문이다(사용도 안 할 코드를 뭐 하러 그리 열심히 작성했을까???).

다시 한번 고객들에게 가치를 제공하는 지속 가능한 서비스를 구현하기 위해서는 최초 출시까지의 속도뿐 아니라 이후 지속적인 요구사항 반영 및 개선이 중요함을 알 수 있다.

이제 왜 최초 출시 이후 왜 개발 속도가 저하되는지 알아보자.

설계 체력 가설 - 기술 부채

이 그림은 https://martinfowler.com/bliki/DesignStaminaHypothesis.html 에서 설명한 "설계 체력 가설"이라는 그림에 약간의 설명을 추가한 그림이다.

설계수익선(design payoff line) 이전에는 설계가 좋지 않은(no design) 시스템이 좋은 설계(good design)를 갖는 시스템보다 누적 기능을 더 빨리 제공한다. 하지만 설계수익선을 지나면 좋은 설계를 가진 시스템은 지속적인 속도로 기능을 출시할 수 있지만, 좋지 않은 설계를 가진 시스템에서는 급격하게 출시되는 기능의 수가 줄어드는 것을 볼 수 있다. 이렇게 되면 후발 업체는 선발 업체의 검증된 비즈니스 모델을 가지고 시작하면서 빠르게 추적하여 선발 업체를 추월할 수 있게 되어 어찌 보면 고생해서 남 좋은 일만 시켜주는 꼴이 된다.

대개 품질이 좋은 제품은 비싸다. 스마트폰만 보더라도 거의 모든 경우 비싼 제품이 품질이 좋다. 그래서 좋은 설계를 갖는 소프트웨어도 비용이 비싸다고 생각하는 경우가 많다. 

한 5년 정도 전에 모두가 알만한 글로벌 탑 레벨의 IT 회사에 다니는 후배와의 대화가 기억이 난다. 후배는 그 회사에서 TDD, 리팩터링 등 품질을 높일 수 있는 기법들을 사용하지 않고 있는 것을 보고 팀장님에게 왜 안 쓰냐고 물었다고 한다. 그 팀장님은 그렇게 개발을 하려면 너무 인건비가 비싼 개발자를 채용해야 해서, 차리리 QA를 활용한다고 답했다고 한다. 이 답변이 단기적(설계수익선 이전)으로는 맞을 수 있지만 장기적으로는 틀린 말이라고 후배와 동의했었다.

부채는 의도적이어야 상환할 수 있다. 출시 속도를 위해 충분히 좋은 설계를 만들 수 있음에도 불구하고 의도적으로 부채를 만들었어야 한다. 부채는 상황해야 한다. 상환할 능력이 없는 부채는 파산을 부를 뿐이다.


지속 가능한 개발

지금까지 지속 가능한 서비스를 위해 향후 변경 비용을 낮추는 품질을 위한 좋은 설계가 중요하다는 것을 알아봤다. 이제부터는 본인이 경험한 개발 환경의 변화 측면에서 어떻게 하면 지속 가능한 개발을 할 수 있는지 의견을 제시해 보겠다.

1. 클라이언트/서버 시대

처음 개발자로서 경력을 시작했을 때 유닉스 서버에 텔넷으로 접속해서 vi로 코딩을 했었다. GUI 클라이언트는 윈도우즈 PC에서 개발했지만 서버 로직은 서버에 접속해서 텍스트 편집기로 개발을 하고, 빌드, 배포를 했었다.

이때는 세밀한 지도가 필요했다. 내비게이션, 스마트폰이 없던 때 어떤 장소를 찾아가기 위해 지도가 필요했던 것처럼 서버에서 텍스트 에디터로 코딩을 하려면 지도 역할을 하는 잘 설계된 설계 문서가 필요했다.

이러한 사전 설계된 문서는 많은 예측에 기반했었던 것 같다. 동작하는 코드 없이 추측을 해서 설계를 했었다.

개발을 하다고 후에 설계 결함이 발생했을 때 꽤 많은 부분은 설계를 고치기 어려워서(매몰비용 오류 sunk cost falacy) 설계대로 개발을 하기도 했었던 것 같다. 그래서 20%의 코드만 사용된 것 같다.

경쟁 상황은 매우 낮았던 것 같다. 전공하지 않으면 제대로 된 개발자로 일하기 어려웠고, 서비스도 대개는 특정 기업을 위한 것이 많아서 타업체와의 경쟁은 입찰 때 정도가 전부였던 것 같다.

2. 인터넷 시대

그러다 인터넷 브라우저가 활성화되면서 여러 측면에서 경쟁이 가속화되었다. 90년대 말만 해도 html을 비전공자가 쉽게 만들 수는 없었던 것 같다. 하지만 브라우저가 활성화되면서 초등학생도 만들 수 있게 되었다.

이때는 서버에 접속해서 텍스트 에디터로 개발하지 않고, 자신의 노트북에서 IDE를 이용해서 개발을 하고, 실행시켜 볼 수 있었다.

사전설계 방식이 아닌 좀 더 애자일한 방식으로 개발할 수 있다. 이때 나는 XP(eXtreme Programming)에 흠뻑 빠졌던 것 같다. TDD로 개발을 하려고 노력을 했었고, 나중에 mocking을 통해 지속적으로 협력 인터페이스를 찾아서 외부(controller, service 등)에서 안(domain)으로 들어오면서 개발하는 방법을 많이 사용했었다.

이때의 경쟁 상황은 이전보다는 강해졌지만 지나 보니 그리 높지는 않았던 것 같다. 이때 나는 스타트업과 Daum에서 개발을 했는데, 특히 Daum에서 개발을 할 때는 우리 경쟁자는 Naver 외에는 없는 것 같았다. 전 국민을 상대로 높은 트래픽을 수용할 수 있는 서비스를 제공하려면 IDC가 필요했는데, 대국민 서비스를 할 수 있는 IDC를 가진 회사는 Daum, Naver 정도였던 것 같다.

3. 모바일 시대

그러다 iphone이 출시되었다. 한국에는 2009년에 들어온 것 같다. 이때부터는 무한경쟁의 시대가 된 것 같다. 대규모의 IDC를 가지고 있지 않은 개인 사업자들도 모바일 앱을 만들어서 경쟁에 참여할 수 있었다.

이제 대기업도 보다 더 애자일하게 개발할 필요가 생겼다. 그러면서 "지속 가능한 서비스"에서 언급한 문제들이 발생했었던 것 같다. 작은 덩치로 재빠르게 움직이는 스타트업에 대응하기 위해서는 빨리 만드는 것이 중요해졌기 때문이다. 반면 나처럼 신규 개발을 하는 만큼 기존 서비스를 운영하고 개선하는 업무를 많이 하는 사람들에게는 품질도 여전히 중요하게 되어 속도와 품질 사이의 갈등이 깊어졌었던 것 같다.

Daum, Kakao를 고치고, SKPlanet/11번가를 거치면서 이러한 갈등 속에서 이리저리 노력을 했었던 것 같다.

그러다 작년 6월 케이타운포유(https://www.ktown4u.co.kr/)에 합류하면서 고민의 가속화되었다. 작은 회사이고, 개발 인력도 적다 보니 속도와 품질 모두가 중요했다. 

나는 초기에 품질을 강조했다. 그러면서 고민이 들었다. 속도 아니 어떤 것이 정말 좋은 품질일까에 대한 고민이었다. 지금 내가 잘하기 위한 역량이 80점이라고 할 때 내가 지금 90점, 100점을 받기 위해 노력하는 것이 맞을 것인가에 대한 고민이었다. 여러 번 생각할수록 지금은 80점을 빨리 받고, 후에 내 역량과 도메인 지식이 많아졌을 때 90점, 100점을 받기 위해 노력하는 것이 맞다는 생각이 들었다.

그래서 지금은 Outside-in (TDD) 방식으로 개발을 하자고 많이 얘기한다. 동작하는 뼈대(Walking Skeleton), 수직 슬라이스(Vertical Slice)(https://github.com/msbaek/presenting-tdd 에서 3. Outside-in TDD with Vertical Slice 슬라이드 참고) 방식으로 개발하는 방법을 많이 공유하고, 그렇게 개발을 하고 있다. 수직 슬라이스 방식으로 구현하면 쿼리(읽기) 기능의 경우 Controller에 거의 모든 기능을 구현해서 빠르게 구현할 수 있게 된다. 커맨드(변경) 기능의 경우도 최소한의 코드로 빠르게 구현을 한다. 배포 후에 새로운 기능을 추가하거나 변경이 필요할 때 리팩터링을 통해 설계를 개선한다. 리팩터링은 동작하는 코드 없이 종이나 화이트보드에 추측/가정/예측 등을 통해 진행했던 사전설계 방식과 달리 동작하는 코드를 가지고 설계를 해서 빠른 피드백을 통해 안정감을 준다. 

다만 동작, 배포된 후에 필요한 경우 리팩터링을 통해 설계를 개선할 수 있는 역량이 있어야 한다. 그렇지 않다면 설계는 빠르게 부패할 것이기 때문이다. 이런 경우라면 어쩌면 사전설계를 하는 것이 더 좋은 방법일 수도 있을 것 같다.

케이타운포유에서는 코드리뷰를 통해 여러 개발자들이 설계가 부패하지 않도록 노력(감시?)하고, 좋은 사례를 주간 세미나 등을 통해 공유하며 역량을 쌓고 있다. 시간이 지나면 지금 우리의 노력이 부족했는지, 성공적이었는지 평가를 받게 되겠지만, 지금 우리의 노력은 매우 의미 있다고 생각한다. 적어도 나는 좋은 코드리뷰 사례를 정리해서 공유하고, 내가 얻은 지식을 공유하여 우리의 개발 활동에 도움이 되는 것을 느낄 때 행복을 느끼기 때문이다(행복은 무게가 아니라 빈도가 중요하다 ^^)

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari