소프트웨어 엔지니어링이란?
한 조직이 소프트웨어를 구축하고 유지보수하는 데 이용하는 모든 도구와 프로세스
시간의 흐름 위에 순간순간의 프로그래밍을 모두 합산한 것
코드의 가치를 오래도록 잘 지켜내는 것
코드베이스의 지속 가능성을 높이기 위해 엔지니어링 규율 자체를 엄격하게 만드는 것
S/W의 지속 가능성이란? 기존 기능을 운영할 수 있으며, 변경 요청에 대응할 수 있도록 소프트웨어를 관리하는 것
기반 기술이나 제품이 지향하는 길로 나아가는 데 필요한 잠재적인 변경에 대응할 역량 자체가 없다면 어떻게 될까?
소프트웨어 프로젝트의 기대 수명(expected life span)과 업그레이드의 관계
대부분 S/W 프로젝트는 5년 이내에 업그레이드를 했으며, 전환 시점은 대체로 5~10년 사이임
확장 가능성
수명이 긴 S/W 일수록 '동작한다' 는 조건을 넘어 '유지보수 가능하다'라는 조건이 중요해진다.
go beyond working
변경 비용이 시간의 흐름에 따라 증가하는 시스템은 확장 가능(scalable)하지 않은 시스템이며, 이러한 상태를 방치하면 결국 갈아 엎어야 하는 시스템이 된다.
- 빠른 기능 구현에 집중
- 최소한의 코드 관리
- 공통 로직이 잘 정의되어 있음
- 가급적 중복 소스를 만들지 않음
- 읽기 쉬운 네이밍 규칙을 가지고 있음
- 리팩토링 문화는 정착되지 않음
- 빨리 빨리에 집중
- 코드 관리 체계 약함
- 정리된 공통 코드가 없어서 각자 유틸리티성 코드를 만들어서 사용
- 빨리만 개발할 수 있다면 copy-paste를 아무런 꺼리낌 없이 사용
- 메소드 분리 등 신경쓰지 않고, 기존 로직에 새로운 기능의 코드를 계속 추가
- 시간이 지날수록 로직이 파악 안되며, 똥밭에서 X을 피해가며, 새로운 X을 늘려가는 방식의 개발
- 시간이 갈수록 새로운 요구사항을 구현하고, 테스트하고, 디버깅을 하는 데 시간이 오래 걸림
- 그런데 의외로 많은 개발팀이 이렇게 일하면, 전체의 80%가 넘는 조직과 S/W가 이런 방식으로 관리되고 있다.
- 기능 추가와 관리 가능한 코드 유지를 병행
- 코드 관리 체계가 있음
- Pull Request에 대해 코드 리뷰하는 문화를 가지고 있음 - 형식적이 아닌 진정한 코드 리뷰
- 클래스 설계, 리팩토링 등 코딩 실력이 상향 평준화되어 있음
- 최소한 절대 중복소스를 만들거나, 기존 로직에 메소드 분리없이 새로운 기능을 추가하는 수준은 벗어남
- 기능추가 보다 유지 가능한 시스템 상태가 더 중요한 가치임을 구성원 모두 인식
- Good 개발팀의 문화는 기본적으로 가지고 있음
- Pull Request를 매우 중요시 하며, 개발팀의 합의가 안되는 코드는 merge 하지 않음
(중요 : 유지 가능한 시스템 >> 기능 추가)
- Pull Request를 매우 중요시 하며, 개발팀의 합의가 안되는 코드는 merge 하지 않음
- TDD, DDD, Agile 등을 시스템 수준에 맞춰서 적절하게 적용하며,
시스템에 맞는 SDLC(Software Development Life Cycle)를 지속적으로 개선함 - 엔지니어링 개념으로 지속적으로 유지보수성을 높이며, 성능 개선 등을 실시
- 비지니스 로직 개발자는 비지니스 로직에 집중할 수 있도록
비지니스 로직 외적인 기능을 지속적으로 공통 로직으로 분리 - 반복되는 운영 작업을 시스템 처리로 지속 이관
- 시간이 지날수록 코드의 복잡도가 개선되며, 일정 개선을 거친 이후 이 수준을 유지
코드 관리만 문제인가?
위의 내용은 모두 신규 코드를 만들고 기존 코드를 관리하는 부분에 대한 설명이었다.
그렇다면 코드 관리만 잘되면 훌륭한 시스템, 훌륭한 엔지니어링 문화를 갖춘 조직이라고 할 수 있나?
개발자 또는 엔지니어인 당신이 보기에 위의 그래프는 어떤 그래프로 보이나?
- 시스템의 응답 속도
- 주기적으로 성능 저하의 원인을 찾아 튜닝 - 인프라 규모
- 불필요한 인프라 정리 및 비용 효율적인 인프라로 전환 - 저장 스토리지
- 더 이상 불필요한 콘텐츠 삭제
- 백업 콘텐츠는 더 값이 저렴한 스토리지로 이관
*특히 IaaS, PaaS의 경우에는 주기적인 정리가 비용 효율화에 상당히 중요함
더 이상 감당할 수 없을 정도로 고정 비용이 증가하는 순간 Cloud를 사용하는 장점이 모두 사라짐 - 빌드 & 배포에 걸리는 시간
- 빌드 배포에 걸리는 시간이 감당하기 힘들 정도로 지연이 되기 시작하면 도메인 / 모듈단위 빌드 분리
- Agile 팀으로 전환 : 팀이 담당하는 업무 도메인이 커지면 팀과 모듈(IntelliJ의 모듈, Eclipse에서는 프로젝트)을 분리
조직에서 코드를 작성하고, 관리하는 데 활용하는 모든 것이 리소스(인력, 시간, 비용) 측면에서 관리할 수 있는 수준을 유지해야 한다.
확장성을 유지하는 방법
✔︎ 정책(Policy)
유용한 정책과 절차는 S/W 개발 과정에 어려움이나, 막연한 두려움을 해소해 준다. 모든 최신 기술과 방법을 모두 적용하라는 말이 아니라, 조직과 S/W의 규모에 맞는 적절한 정책이 있다면 확장성을 유지하기 쉽다는 의미이다.
예) 비욘세 규칙 : CI 테스트(자동화 테스트)에서 발견되지 않는다면 기능을 사용한 측에서 책임을 지지 않는다.
비욘세의 히트곡 Single Ladies의 후렴구에서
"네가 좋아했다면 반지를 끼워줬어야지"
If you like it then you should have put a ring on it
"그렇게 중요한 로직이었으면 테스트 코드를 만들어 뒀어야지"
코드를 사용하거나, 추가 수정하는 담당자가 기존의 테스트 케이스를 일일이 확인 및 수동으로 수행하지 않고, 새롭게 사용하는 부분이나, 수정한 로직에 대해서만 테스트 케이스를 추가하면 되도록 하는 규칙
(단, 기존 테스트 코드는 모두 통과가 되도록 유지해야 함)
✔︎ 안정성
규칙적인 릴리즈, 빌드의 사이즈, 설계(리뷰)/변화의 관리(PR)는 S/W를 안전한 수준으로 유지하는데 큰 도움을 준다.
✔︎ 자동화
자동화는 반복적이고, 소모적인 업무를 없애고, 실수를 줄여주며, 개발자가 개발에 집중할 수 있도록 한다.
꾸준히 자동화를 진행한 조직과 그렇지 못한 조직은 시간이 갈수록 유지보수 효율이 떨어지며,
자동화를 진행하지 않고, 인력으로 처리하는 업무를 점점 늘려가는 조직은 더 많은 인력을 투입해도 지속적으로 더 많은 인력이 필요한 비효율적인 조직이 되며, 손익분기점을 넘어서는 시점부터는 이미 망해가는 시스템이 된 이후이다.
✔︎ 순응(Comformity) : 통합과 일관성
시스템이 통합되지 않고, 일관성이 관리되지 않는 경우에는 시간이 지날수록 더 많은 비용이 소요되게 된다.
통합 : 예를 들어 초기 개발된 시스템과 최근에 개발된 시스템의 Library 및 버전이 다르고, 시간이 지날수록 사용되는 라이브러리, 버전이 각양각색이 되면 유지보수 효율이 점점 떨어지게 된다.
인프라(S/W 버전을 포함)는 더 자주 업데이트 할수록 유지보수가 오히려 쉬워진다. 변경이 있을 때마다 업그레이드를 하고, 호환성을 유지하는 소스 변경을 수시로 해 두면, 다음번 업그레이드도 쉬워진다. 마이너한 업데이트는 거의 늘 호환성이 유지가 되거나, 약간의 변경으로 기존 기능을 지원할 수 있다.
몇 년을 묵혔다가 한방에 업그레이드를 하는 경우 호환되는 라이브러리를 찾지 못하거나, 변경사항이 추적되지 않아 큰 고초를 겪게 될 수 있으며, 특히 일정이 정해진 강제 업그레이드를 만나기라도 하면 심각한 Risk를 감당해야 할 상황을 맞게 될 것이다.
일관성 : 표준화된 코드 체계, 관리에 사용되는 시스템 등이 통일되지 않으면 점점 관리가 어려워 진다. 개발 뿐아니라 기획, 디자인 등 다른 분야에서도 일관되지 않은 산출물 또는 정리되지 않은 산출물은 유지보수를 힘들게 만든다.
✔︎ 익숙함
설계를 공유하고, 코드를 리뷰하며, 테스트 코드를 작성하고, 지속적으로 리팩토링하고, 최신 OS, 최신 라이브러리로 지속적으로 업그레이드를 하고, 반복 업무를 자동화 하고, 성능을 개선하고, ... 이 모든 유지보수에 도움이 되는 업무들을 당연하고 자연스럽게 수행하도록 조직과 구성원이 익숙해지도록 만들어야 한다. 15일을 하면 습관이 되는 것처럼, 한번에 하나씩 좋은 습관을 추가해 나가는 것이다.
✔︎ 전문성
두 말할 것도 없이 전문성, 기술력, 숙련도가 올라가면 퀄리티와 효율도 올라간다.
조직원 모두가 모든 분야에서 전문가일 필요는 없다. 다만, 조직원 개개인이 각 분야별로 전문가로 성장한다면 조직 전체의 전문성이 올라가고, 관리하는 시스템의 확장성과 안정성도 동반 상승한다.
원점 회귀(Shift left zero)
개발 과정에서 문제를 조기에 발견할수록 비용이 적게 든다.
컨셉단계(요구사항 수집, 범위 정의) >> 기획(기획 리뷰) > 설계(설계 리뷰) > 구현(자동화 테스트) > 리뷰(PR) >> 테스트
왼쪽으로 옮기는 행위를 원점 회귀(Shift left zero) 라고 한다.
위의 내용은 IT 업계에 종사하는 누구나 잘 알고 있는 내용이다. 그렇지만, 정말 잘 이해하고 있고, 이를 잘 하고 있는 조직은 얼마나 될까?
원점 회귀를 제대로 지키지 않는 대표적인 예
- 일단, 기능부터 개발하고, 보안과 관련된 부분은 기능을 구현한 이후에 고민해 봅니다.
- 비슷한 예) 일단, 개발해 놓고, 정산과 관련된 부분은 추후에 따져 봅시다. (올가 매장전용 쿠폰) - 일단, 이 기능까지만 만들어 주시면 됩니다. 우선 써보고, 쓰다가 문제가 있으면 다시 요청할께요.
- SW가 HW보다 수정하기 쉬워서 SW는 맞지만, 나중에 수정하면 처음부터 검토하는 것보다 비용이 훨씬 많이 발생함을 인식해야 함
- 현재 개선해야 할 문제가 무엇이고, 추가 기능을 통해 어디까지 개선할 수 있는지를 명확히 파악하지 못했다는 반증
- S/W 기능, 추가 개선 작업에서 가장 많이 발생하는 유지보수를 어렵게 만드는 케이스
- 일단 만든 기능 이후로 끝이 보이지 않는 수정 사항이 발생함
(20년 미출 개선 사례. 미출 원인이 제대로 파악되지 않은 채 양파껍질처럼 지속적으로 추가/변경 요청) - 사용 목적, 목표, 기대성과를 명확하게 설정하지 않은 채 일단 개발부터 해달라는 요청 사항
- 올가 매장 전용 기획전 / 매장 전용 쿠폰 / MFC 권역 추가 - 개발자가 중요한 프로세스를 무시하고 다음 단계로 진행하는 경우
- 중요 테이블 설계 및 로직 추가가 포함되었으나, 리뷰 없이 테스트 단계까지 진행
- 복작한 로직 개발이 진행되었으나, 코드 리뷰 생략
- 리뷰를 진행했으나, 내 담당이 아니라고 형식적으로만 자리를 채움(모두가 같은 생각이면 리뷰는 왜?) - API에서 보안과 관련된 기능을 나중에 추가한다면..?
- API 인증 방식 변경, 인증키 발급, API를 이용하는 Client가 인증을 적용하도록 강제화
- 만약 제공된 API가 많거나, Client가 많다면... API에 보안 기능을 적용하기 위해 얼마나 많은 비용이 들어갈까?
빌드 시스템
트위터 여론조사에 따르면 60~70%의 소프트웨어는 지금도 개발자의 로컬 PC에서 빌드가 된다고 함
개발자가 컴파일하고, 수동으로 배포하는 시스템은 개발자가 일할(개발할) 시간이 줄어든다는 의미이며, 인건비를 상승 시키는 요인
CI/CD를 개발/구축하는 것은 시간/비용/자원이 들어간다. 그렇지만, CI/CD는 지속적으로 개발하고, 테스트하고, 배포하는 조직에서는 거의 대부분의 경우 가장 중요한 엔지니어링 항목으로 업무 효율화에 직접 기여한다.
근무 태만한 프로그래머의 합법적인 핑계
CI/CD를 갖춘 소프트웨어라도 시간이 지나면서 코드가 많아지면, 컴파일, 테스트, 빌드 시간이 점점 늘어난다.
대안은 앞서 언급한 것처럼 배포의 단위를 나누는 것이 최선이며, 빌드에 들어가는 시간이 비효율적으로 큰 덩어리의 거대한 소프트웨어를 많은 개발팀원이 함께 운영하고 있다면, 피자 한판 조직이 왜 피자 한판이어야 하는지는 단지 피자 때문만은 아님을 기억하라.
'Wise saying' 카테고리의 다른 글
팀워크 이끌어내기 (0) | 2022.09.28 |
---|