동작하는 것은 누구나 만들 수 있다
소프트웨어 잘하는 방법에 대해서 생각을 풀어내다 보니 그게 진짜 필요한 것인지 의문이라는 질문이 저 멀리서 들려오는 듯했다. 그래서 오늘은 비기능 요구사항에 대해서 이야기해보려고 한다. 잘하는 방법을 논할 때 빼놓을 수 없는 것, 실력을 논할 때, 품질을 말할 때 빠지지 않는 비기능 요구사항에 대해서 짧고 굵게 이야기해 보려 한다. 오늘 이야기에서 앞서 SoC와 인터페이스를 강조했던 이유를 찾을 수 있을 것이다.
무언가를 배울 때 내가 할 수 있는 것들이 조금씩 늘어난다. 처음에는 아주 기본적인 자세를 잡는 것, 혼자 시작하는 것조차 못하다가 하나씩 스스로 할 수 있게 되고, 하나씩 익숙해진다. 무언가를 할 수 있다는 것은 매우 직관적이고 명확한 성취 결과이기 때문에 금방 우쭐해지기도 한다. 나도 이제 접영을 할 수 있다고! 기타로 한 곡을 끝까지 연주할 수 있게 되었다는 사실이 나에게 어떤 자격이 생긴 것 같기도 하고, 무언가 무에서 유를 창조한 것 같은 느낌에 우쭐해지기도 한다.
소프트웨어도 마찬가지다. 코딩이나 프로그래밍을 처음 배운 입문자들은 'Hello World'라는 간단한 단어를 화면에 출력하거나 샘플 앱을 만들어서 설치해 보는 것으로 시작한다. 그리고 내가 만들고 싶었던 기능을 만드는 방법에 대해서 열심히 학습을 해서 그것을 만들어 낸다. 화면에 내가 만든 프로그램이 실행되고, 내가 의도한 대로 동작했을 때 신경 전달 물질 도파민이 쏟아져 나오는 것을 느낄 수 있다.
처음 한 번이 어렵지 한 번 성취를 맛보게 되면 도파민의 힘으로, 열심히 달려서 다음 단계로 급격하게 성장할 수 있다. 내가 할 수 있는 기술들이 늘어나는 것처럼, 나의 프로그래밍 실력도 늘어나서 이것저것 별 걸 다 뚝딱 만들 수 있는 실력을 갖추게 된다. 그리고 프로그래밍과 컴퓨터, IT 지식이 풍부하게 살찐 나머지 금방이라도 세상을 정복할 수 있을 것 같은 생각이 들고, 뭐든지 요구하는 대로 다 만들어 줄 수 있는 상태에 도달하게 된다. 상황에 따라 다르지만 빠른 경우 주니어 2~3년차면 도달하기도 한다.
내가 프로그래밍을 좋아하는 이유 중 하나는 적은 비용으로 엄청난 것들을 창조해 낼 수 있다는 점이다. 물론 대부분 컴퓨터 안에서 돌아가는 것이지만. 어쨌든 무엇이든 다 만들 수 있을 것 같은 이 기분은 꽤나 즐겁고, 스스로를 당당하게 만들어 준다. 긱들을 봐라 멸치 같은 몸이지만 컴퓨터 앞에선 겁이 없다.
무엇이든 다 만들어 낼 수 있는 상태에 도달하는 이 시점에 자만에 빠지는 경우도 종종 있지만, 반대로 슬럼프와 현타를 경험하는 경우도 많이 있다. 바로 이때가 고수가 될 것인지, 하수로 남게 될 것인지 구분되는 중요한 시점이기도 하다.
소프트웨어 프로그래머들 사이에서 십수 년의 경력직과 2~3년차 주니어는 큰 차이가 없는 경우, 오히려 실력이 역전되는 경우도 많다. 나는 그 차이를 그냥 할 수 있는 사람과 잘하는 사람의 차이로 구분하는데, 그것은 기능과 성능으로 표현할 수 있다. 단순히 어떤 것을 만드는 것, 동작하게 하는 것은 기능이라고 한다. 반면, 그 기능이 어떻게 동작하는지에 대한 것이 바로 성능이다.
직접적으로 간단하게 말하자면 프로그램이 동작하도록 만드는 것은 기본이다. 무엇이든 만들 줄 안다는 것도 분명 뛰어난 일이지만, 그것은 주니어 레벨까지만 인정받을 수 있는 능력일 뿐이다. 시키는 거 꼼꼼하고 빠릿빠릿하게 잘한다는 칭찬은 주니어까지만 칭찬인 것과 같다. 주니어 이상으로 성장하려면 정말 잘하는 것은 시키지 않은 것도 필요하다면 해야 하고, 필요 없다면 과감하게 의견을 내서 방향을 바꿀 수 있어야 하는 것처럼 소프트웨어도 기능 이상의 성능을 목표로 엔지니어링 해야 한다.
앞에서 단순히 성능이라고 했지만, 소프트웨어에서는 비기능 요구사항이라는 것으로 정의하고 있는 품질 속성이 있다. 말 그대로 무엇을 해야 하는지에 대한 동작하는 기능 요구상항이 아닌 어떻게 동작해야 하는지에 대해 요구되는 품질 속성이나 제약 사항을 뜻한다.
- 성능(Performance)
응답 시간, 처리 속도, 처리량 등.
예: “사용자 요청은 1초 이내에 응답해야 한다.”
- 보안(Security)
인증, 권한, 데이터 암호화, 접근 제어 등.
예: “모든 데이터 전송은 HTTPS로 암호화되어야 한다.”
- 사용성(Usability)
사용자 친화적 인터페이스, 직관성, 접근성.
예: “초보자도 10분 이내에 주요 기능을 사용할 수 있어야 한다.”
- 신뢰성(Reliability)
시스템이 안정적으로 동작하는 정도.
예: “24시간 연속 사용 시 오류 발생 확률은 0.01% 미만이어야 한다.”
- 가용성(Availability)
시스템이 사용 가능한 시간 비율.
예: “시스템 가용성은 99.9% 이상이어야 한다.”
- 확장성(Scalability)
트래픽 증가 시 확장 가능 여부.
예: “동시 사용자 수가 10,000명을 넘더라도 성능 저하 없이 작동해야 한다.”
- 유지보수성(Maintainability)
시스템 수정, 개선, 패치 용이성.
예: “모든 기능은 3일 이내에 수정 가능해야 한다.”
- 이식성(Portability)
다른 운영 체제나 환경에서의 실행 가능성.
예: “리눅스와 윈도우 환경 모두에서 작동해야 한다.”
- 규정 준수(Compliance)
관련 법률이나 규정에 대한 준수 여부.
예: “GDPR 규정을 준수해야 한다.”
진정으로 소프트웨어를 잘하고 싶다면 비기능 요구사항을 잘 챙겨야 한다. 내가 만든 소프트웨어에 자신이 있다면 스스로 본인 코드와 프로그램의 비기능 요구사항 수준을 평가해 보는 것도 좋다.
내가 특히 강조하는 것은 사용성인데, 요즘처럼 복잡하고 다양한 환경에서 사용자에게 선택받지 못하는 소프트웨어는 쉽게 도태되게 되어 있고, 도태되어 버린 소프트웨어는 그 존재 자체가 의미가 없어지기 때문이다. 심지어 사내에서도 사용성은 중요한데, 다른 부서에서 요청받은 대로 동작하는 기능만을 만드는 것은 정말 하수 또는 초급 프로그래머나 하는 일이다.
요즘에는 국산차도 아주 고급지게 나오지만, 내가 어릴 때까지만 해도 국산 자동차 업체는 차가 고장 없이 잘 동작하도록 만드는 것에 급급했다. 반면, 수입차는 빠르고 튼튼한 것은 물론이고 차량 내부의 버튼 위치나 깜빡이 소리까지도 편리하고 고급스러웠다. 소위 말하는 감성품질이 뛰어났는데, 그것이 바로 사용성의 한 종류다.
차만 그런 것이 아니다. 아이폰이 한참 인기를 끌고 있을 때, 많이 회자되었던 것이 터치가 부드럽다는 것이었다. 아이폰은 자체 운영체제의 특성상, 별도의 런타임을 사용하지 않기에, 조금 더 빠르게 사용자의 터치 입력을 처리할 수 있었는데 소비자들은 그 작은 차이에 열광했다. 홈 화면에 손가락을 가져다 놓고 좌우로 빠르게 움직일 때 이질감이 덜하다는 것이다. 심지어 애플 매장 직원도 애플스토어에 방문한 나에게 그걸 자랑했다.
화면이 터치에 빠르게 반응하는 것이나 깜빡이 소리가 부드럽고 자연스럽게 재생되는 것은 기능상 큰 차이도 없고, 문제가 되는 것도 아니다. 하지만 사용자 경험에는 분명한 차이가 있고, 그 차이로 내가 만든 제품, 나의 소프트웨어는 외면받을 수 있다는 것을 잊어서는 안 된다.
내가 만든 코드가 고급 외제차나 아이폰과 같은 느낌으로 사용자들에게 선택된다면 얼마나 기분이 좋은지 생각해 보면 좋을 것 같다. 다른 개발자들이나 유관 부서에서 내 코드, 내 프로그램을 인정하는 그 순간의 짜릿함을 아는 개발자는 이러한 비기능 요구사항도 꼼꼼하게 챙기게 되고, 자연스럽게 훌륭한 엔지니어로 성장하게 된다.
비기능 요구사항에서 하나 더 강조하고 싶은 것은 유지보수성이다. 사용성은 내 코드가 명품으로 인정받을 수 있는 중요한 속성이지만 유지보수성은 내 코드가 제품으로서 성공할 수 있는지 결정하게 되는 더 중요한 속성이다.
개발자는 프로그래머라고 불리기도 하고, 엔지니어라고 하기도 한다. 그 둘은 구분 없이 사용되곤하며, 프로그래밍과 엔지니어링은 차이를 인식하고 사용하는 일은 드물다. 결과적으로 소프트웨어 제품을 만드는 것은 비슷하지만 사실 큰 차이가 있다.
구글의 소프트웨어 엔지니어링 책에서 그 차이를 잘 소개하고 있는데, 프로그래밍은 순수하게 프로그램을 만드는 작업을 의미한다면, 엔지니어링은 프로그램을 만들기 시작할 때부터 사라질 때까지 모든 과정을 포함하는 것이라고 말하고 있다.
소프트웨어 엔지니어링은 흐르는 시간 위에서 순간순간의 프로그래밍을 모두 합산한 것이다 - 구글 엔지니어는 이렇게 일한다
재미나 학문의 목적으로 단순히 프로그램을 만드는 것이라면 엔지니어링이라는 표현이 잘 어울리지 않는다. 엔지니어링은 기본적으로 주어진 환경에서 다양한 방법을 동원해서 시스템의 생산성과 효율성을 높이는 일이고, 엔지니어는 단순히 어떤 프로그램이나 시스템을 만드는 것을 넘어 프로젝트에 사용될 기술이나 운용 환경, 유지보수 방법, 비용까지 고민해서 최적의 품질을 달성할 수 있도록 연구하고 실행하는 사람을 뜻하는 것이다.
뛰어난 직원은 자신에게 주어진 업무를 정확하게 잘 처리하고, 훌륭한 직원은 회사 전체 상황을 고려해서 업무를 처리한다. 마찬가지로 뛰어난 프로그래머는 사람들이 인정하는 프로그램을 만들어 내고, 훌륭한 엔지니어는 프로그램의 탄생부터 소멸까지 최적의 비용으로 프로그램을 만들고, 관리하고 동작할 수 있도록 한다.
단순히 인정받는 것을 넘어서 소프트웨어로 성공하고 싶다면 반드시 유지보수성과 엔지니어링 마인드를 잊어서는 안 된다.
당장 내가 성공하지 못한 상태라서 성공을 말하는 것이 조심스럽지만, 사용성과 유지보수성 같은 비기능 요구사항도 잘 챙기는 훌륭한 소프트웨어 엔지니어가 되길 바라는 마음으로 적어낸 아저씨의 애교 섞인 잔소리쯤으로 받아줬으면 좋겠다.