소프트웨어 파괴의 미학 - 불확실성에 대항하는 방법
(kciter.so)- 소프트웨어는 많은 것이 불확실하다.
- 불확실한 이유는 무엇일까?
- 가장 큰 이유는 비즈니스의 복잡성이 존재하기 때문
- 복잡성으로 인해 상황은 계속해서 변하며 이로 인해 개발자의 예측은 높은 확률로 틀린다.
- 공들인 탑이 무너져 그대로 기술부채로 변한다.
- 작은 이유는 지식과 경험의 부족 때문
- 지식과 경험이 없다면 개발자 스스로 만들어낸 기술부채를 만들 수 있음
- 비즈니스의 복잡성은 개발자가 통제할 수 없는 외부 요인, 반면 지식과 경험은 개발자가 통제할 수 있는 내부 요인
- 개발자에게는 세 가지 길이 있음
- 복잡성에 대항하는 것은 무의미하다고 생각하는 염세주의적 길
- ’어차피 변경될테니 그냥 하자’, ‘기술은 무의미해’와 같은 말을하게 됨
- 편하고 안락한 길이기에 자신도 모르게 이 길을 선택 할 수 있음
- 복잡성을 외면하고 이상적인 가상만을 생각하는 길
- 자신이 이상적이라 생각하는 한 가지 기술로 모든 것을 해결할 수 있다고 믿음
- 경직되고 획일화된 사고를 가지게 됨
- 개발자는 쉽게 빠질 수 있는 길이지만 빠져나오기 힘듬
- 복잡성을 받아들이고 맞서 싸우는 길
- 완벽할 수 없다는 것을 받아들여도 계속 더 나은 길을 찾으려 하는 것
- 어렵고 견뎌야하는 길
- 소프트웨어 개발은 계속해서 복잡성과 싸워왔음
- 아키텍처, 방법론, 애자일 등…
- 다음은 무엇이 등장할까?
- 복잡성에 대항하는 것은 무의미하다고 생각하는 염세주의적 길
- 파괴 지향 개발
- 현실을 보면 어차피 지워진다라는 염세주의적 생각에 빠지기 쉽다.
- 우리가 열심히 작성한 코드가 실패작이라 느끼며 스스로 지우는 것은 매우 고통스럽기 때문
- 차라리 거꾸로 생각하여 차라리 잘 지울 수 있게 만드는 것은 어떨까?
- 파괴는 좋은 것인가?
- 파괴가 없다면 새로운 것은 탄생할 수 없음
- 소프트웨어에서 볼 수 있는 파괴는 크게 두 가지 - 피벗과 리팩터링
- 피벗은 조직과 제품이 더 나은 길을 선택할 수 있게 해줌
- 리팩터링은 소프트웨어의 생명은 더 연장하기 위해서 꼭 필요한 일
- 그래서 파괴 지향 개발이란?
- 언젠가 코드가 파괴될 것이라는 사실을 받아들이고, 그것을 지향하여 개발하는 방법론
- 세 가지 대원칙을 지향
- 불확실성이 있다면 가능한 만큼 불확실성을 줄인다.
- 여러 방법을 선택할 수 있다면 파괴하기 쉬운 쪽을 선택한다.
- 필요한 것만을 유지한다. 따라서 필요 없는 것은 전부 지운다.
- 분석 -> 경계 분리 -> 코드 구현 -> 복잡성 제거
- 내부 요인에 따른 불확실성을 줄이고 어쩔 수 없는 외부 요인으로 인한 파괴에 대비하는 것이 핵심
- 경계 분리
- 불확실성은 변화율이며 이를 기반으로 분리하는 것이 가능
- 개발자는 외부 요인에 대비하며 최대한 내부 요인으로 인한 변화율을 줄여야 함
- 각 요인의 변화율은 조직마다 다를 수 있기 때문에 고정적인 수치로 표현하는 것은 불가능 -> 휴리스틱한 방법으로 측정
- ex) 스토리 포인트 측정
- 무엇을 기준으로 분리할지 추상화 레벨을 결정해야함
- 파괴 가능성
- 구현을 할 때는 대원칙에 따라 파괴하기 쉬운 쪽을 선택
- 독립성, 인지가능성, 통제가능성을 고려하여 파괴 가능성을 판단할 수 있음
- 독립성은 결합도와 응집도의 정도, 단일 책임 원칙을 어느정도로 지켰는지로 판단
- 인지가능성은 개발자가 코드를 보고 이해할 수 있는 정도
- 통제가능성은 개발자가 통제할 수 있는 영역인지를 판단
- 복잡성 제거
- 불필요한 것이 있는지 확인하고 제거해야 한다. 즉, 최종적으로 코드베이스엔 필요한 것만을 남겨야 함
- 마감일 등에 대한 문제로 인해 작업하는 것이 어렵다면 기록만 해두고 작업해도 문제는 없음
- 내부 요인은 통제 가능하기 때문
- 파괴에 대비하여 최대한 단순성을 유지하는 것이 핵심
- 코드 파괴의 기술
- 코드를 잘 지우는 여러 원칙과 방법이 있음
- 단계 쪼개기 (리팩터링 패턴)
- 참조 투명성 지키기
- 단일 책임 원칙 지키기
- 인터페이스 분리 원칙 지키기
- 스트랭글러 무화과 패턴
- 메서드 전문화
- 중복 코드 작성
- 변화율 기록
지식과 경험이 부족해서 코드 부채를 만든다는 말은 별로 공감이 안가네요
-> 요구사항 구현에 주어진 시간이 모자랄 수도 있고, 협업하는 경우 타인과 조화를 위해 약간의 기술부채를 감내하는 경우도 있고 상황은 다양하다고 생각합니다.
지식과 경험을 개발자가 통제할 수 있는 내부 요인으로 보는 것도 잘 모르겠어요
-> 비즈니스는 복잡해서 어떤 상황이 닥쳐올지 예측할 수 없는데 모든 경우의 수를 그때그때 공부할 수도 없죠. 그 상황에 닥쳐서 공부를 하더라도 다음번엔 전혀 새로운 문제가 발생해 지식이 쓸모없어질 수도 있고요.
글 잘 읽었습니다. 조직의 스테이지에 따라 무엇이 이른 최적화고 오버엔지니어링이냐도 달라지는 듯 해요. 어차피 다시 짜야할 코드기도 하면서 다시 짤 순간이 올지 안올지도 모르는 코드라는게 어려운 지점이네요. 저는 xxx 서비스, 기능이 없어진다 했을 때 yyy 코드, 데이터는 어디에 있는게 적절한가? 라는 질문으로 판단할 때도 있는데 다른 분들의 방법도 궁금하네요.
코드 말고도 데이터나 스키마도 없어지거나 변경될 수 있는지 생각하는 편입니다
- DB 스키마, 프로토콜(REST API 같은), 기능 세 가지 분류 중 코드가 어디에 해당하는지 생각합니다. 스키마와 프로토콜은 필연적으로 회사 내부의 코드나 외부에 전파되기 때문에 나중에 바꾸려면 혼자 며칠만에 해결할 수 없고 협업이 필요하게 됩니다. 따라서 설계 단계에서 시간을 좀 더 씁니다
- 코드가 다루는 데이터의 라이프사이클과 휘발성을 생각합니다. winterjung님께서 고민하시는 서비스가 없어질때의 상황도 포함이 될 것 같네요. OLTP에서 얘기하는 원장, 거래, 이력 테이블 분류도 이런 고민을 시작해보는 방법이 될 수 있을 것 같습니다