클린아키텍처를 스터디하면서 책의 내용, 토론한 내용, 개인 생각을 정리한 글입니다.
1부 1장, 2장
1부
1부
1장 설계와 아키텍쳐란
프로그램이 동작하도록 만드는 데 엄청난 수준의 지식과 기술이 필요하지는 않다.
누구든지 할 수 있는일이다.
동작은 한다. 프래그램을 동작하게 만들기는 그리 어려운일이 아니기 때문이다.
하지만 프로그램을 동작하게만 하는 수준이 아닌, 제대로 만드는 일은 전혀 다르다.
소프트웨어를 제대로 만들게 되면 마법과 같은 일이 벌어진다.
소수의 프로그래머 만으로 유지보수와 지속적으로 동작할 수 있도록 만들 수 있다.
설계와 아키텍처의 차이란?
둘 사이에는 차이가 없다.
'아키텍처'는 저수준의 세부사항과는 분리된 고수준의 무언가를 가리킬때 사용된다
'설계'는 저수준의 구조 또는 결정사항 등을 의미할 때가 많다.
둘 사이에 차이가 없는 결정적 이유는, 모든 고수준의 결정사항을 지탱하는 그 밑의 모든 세부사항들을 자세하게 확인해보면,
저수준의 세부사항과 고수준의 결정사항은 전체 설계의 구성요소가 된다.
이 둘은, 개별로는 존재할 수 없고, 이 둘을 구분짓는 경계는 뚜렷하지 않다.
고수준에서 저수준으로 향하는 의사결정의 연속성만이 있을 뿐이다.
소프트웨어 아키텍처의 목표
소프트웨어 아키텍쳐의 목표는 필요한 시스템을 만들고 유지보수하는데 투입되는 인력을 최소화 하는데 있다.
책 내용에 보면, 개발자의 임금 비용과 코드 생산성, 그 둘을 바탕으로 코드당 비용을 계산해 본 그래프가 있다.
간단하게 설명하자면, 해마다 개발자 채용 수가 늘어나지만, 코드 생산성(책에서는 간단히 코드 라인수로만 측정)은 어느순간 늘어나지 않는다.
개발자 숫자는 늘어나지만, 코드 생산성이 늘어나지 않는다는건, 코드 라인당 비용이 매우 비싸진다고 볼 수 있다.
이 비용이 엉망진창이 되는 이유는
- 시스템을 급하게 만들거나
- 결과물의 총량은 순전히 프로그래머 수로 결정하거나
- 코드나 설게의 구조를 깔끔하게 만들려는 생각을 하지 않았을 때
가장 비용이 크게 올라간다고 보여진다.
결국 그러면 개발자의 생산성은 0에 가까워 진다.
좋은 코드가 늘지않고, 개발자들만 늘어나면 결국 생산성이란 지표는 떨어질 수 밖에 없다.
기능 개발 보다는 엉망이 된 상황에 대처하는데 소모하기 때문이다.
열심히 일하지 않는 개발자는 없다.
무엇이 잘못되었나?
토끼와 거북이 우화를 생각해보자.
이 우화의 교훈은 크게 3가지가 있다.
- 느려도 꾸준하면 이긴다.
- 발 빠른 자가 경주에 이기는 것도 아니며 힘센 자가 싸움에서 이기는 것도 아니다
- 급할수록 돌아가라
현대의 개발자도 이와 비슷한 경주를 하며 유사한 자기자신을 과신하는것을 드러낸다
- 아 테스트 코드 짜고 여러방면으로 깔끔하게 짜려면 시간이 너무 오래걸리는데....
- 기획팀이랑 대표님이랑 다른파트에서 쪼잖아.. 빨리만들어야지 그냥
- 좀 더럽고 설계 이상하면 뭐 어때? 지금 코드 짠거 일단 돌아가니까 나중에 수정해야지,
모든 개발자들은 뼈빠지게 일한다. 하지만 그들의 뇌는 토끼와 거북이의 토끼처럼 자고있다.
훌륭하고 깔끔하게 잘 설계된 코드가 중요하다는 사실을 알고있는 그 뇌가 자고있다.
과연 개발자들이 훌륭하고 깔끔하게 잘 설계된 코드가 중요하다는걸 모를까?
당장은 시장에 출시하는게 먼저야 라는 흔해빠진 거짓말에 속는다.
시장의 압박은 절대로 수그러 들지 않기 때문이다.
그렇기에, 이전에 작성한 코드로 돌아가 정리하는 일은 하지 않고, 바로 다음에 만들어야 할 새로운 기능이 기다리고,
다음 기능, 또 다음 기능, 또 다음 기능이 계속 기다리고 있기 때문이다.
결국 코드는 엉망진창이 되고 개발자들의 생산성은 0에 수렴해간다.
개발자가 더 잘 속는 거짓말은
지저분한 코드를 작성하면 단기간에 빠르게 갈 수 있고 장기적으로 볼 때만 생산성이 낮아진다는 견해
이다잘 생각해보자.
지저분한 코드로 그냥 돌아가게 해놓고, 테스트코드 작성 및 테스트도 안하고, 리팩토링도 없으면 단기간에도 빠르게 갈 수 있나?
- 책에 ''제이슨 고먼'' 수행한 실험이 있다.
- 6일동안 간단한 프로그램을 만들고, 일련의 인수 테스트를 프로그램이 통과하면 개발이 완료된 것으로 보았다.
- 이 작업은 간단하여 매일 30분도 걸리지 않았다.
- 첫째, 셋째, 다섯째 날에 TDD를 적용했고, 나머지 3일에는 TDD를 적용하지 않고 코드를 작성했다.
- 프로그램 개발 속도의 결과는 어떻게 되었을까?
TDD를 적용한 날이 적용하지 않은 날보다 대략 10% 빠르게 작업을 왼성되었고,
심지어 TDD를 적용한 날중 가장 느린 날이 TDD를 적용하지 않고 가장 빠른날보다 더 빨리 완성되었다.
우리는 여기서 토끼와 거북이에서 배운 교훈을 기억할 수 있다.
빨리 가는 유일한 방법은 제대로 가는것.
- 책에서는 TDD 한개의 경우에만 대입하여 설명하였지만 다른 것들도 다르지 않다.
- 내 경험상도 그렇다.
- 통상적으로 TDD나 ATDD, BDD등을 이용하여 개발할 때 시간이 더 오래걸린다고들 한다.
- 간단하게 Spring boot로 Controller-Service-Repository 3 Layer 기반으로 API를 만들었었다.
- 테스트 코드를 작성하지 않았을 때는 어떤걸로 테스트 했을까?
- 포스트맨으로 직접 API 테스트
- 스웨거(Api docs)로 직접 API 테스트
- 결과적으로 한 기능을 개발하는데 훨씬 많은 시간이 걸렸다.
- 오류가 난다 -> 콘솔상의 예외를 보고 오류가 난 클래스를 찾아가 직접 수정후 빌드
- 다시 위의 도구들을 가지고 테스트
- 또 오류가 나면 다시 수정, 다시 테스트
- 통상적으로 Junit으로 각 계층(Layer)마다 단위테스트 작성하여 테스트 하는것보다훨씬 많은 시간 소요.
- 결국 느리지만, 제대로 가는것이 중요하다.
- 느리지만, 코드의 안정성 증가 및 개발 시간을 전체적으로 줄어든다고 볼 수 있다고 생각한다.
과신하지 말자.자신이 만든 코드를를 책임져야 한다.
어떤 경우라도 개발 조직이 할 수 있는 최고의 선택지는 조직에 스며든 과신을 인지하여 방지하고,
소프트웨어 아키텍처의 품질을 심각하게 고민하여야 한다.
이 비용은 최소화하고 생산성을 최대화 할 수 있는 설계와 아키텍처를 가진 시스템을 만들라면
결국, 이러한 결과로 이끌어줄 시스템 아키텍처가 지닌 속성을 알고 있어야 한다.
2장 두 가지 가치에 관한 이야기
모든 소프트웨어 시스템은 이해관계자에게 서로 다른 두가지 가치를 제공하는데, 행위(Behavior)와 구조(structure)가 바로 그것이다.
- 여기서 이해관계자는 CEO, 개발자, 기획자, 매니저, 사용자 등이라고 생각된다.
소프트웨어 개발자는 두 가지 모두 반드시 높게 유지해야 하는 책임을 진다.
불행하게도 개발자는 한 가지 가치에만 집중하고 나머지 가치는 배제하곤 한다.
대체로 두 가지 모두 반드시 높게 유지해야하는 책임을 가진 개발자가, 둘 중 덜 중요한 가치에 집중하여 결국 소프트웨어 시스템이 쓸모없게 되어버린다고 한다.
행위(Behavior)
개발자를 고용하는 이유는, 이해관계짜를 위해 수익을 창출하거나 비용을 절약하도록 만들기 위해서다.
이를 위해 개발자는 이해관계자가 기능명세서나 요구사항 문서를 구체화 할 수 있또록 돕는다.
그리고 이해관계자의 기계가 이러한 요구사항들을 만족하도록 코드를 작성한다.
많은 프로그래머가 이러한 활동이 자신이 해야 할 일의 전부라고 생각한다고 한다.
요구사항을 기계에 구현하고, 버그를 수정하는 일이 자신의 직업이라고 믿는다고 한다.
슬픈 일이지만, 그들은 틀렸고, 나 역시도 개발자들은 저 일이 전부가 아니다.
- 내가 생각하기에 개발자들의 목표는 상품을 만들어 내는것.
- 구현하고 버그를 수정하는 일이 다가 아니다. 이것들은 일부일 뿐이다.
- 개발자들은 오너십이 필요하다. 자신이 작성한 코드와, 만든 기능에 책임감을 가져야 한다.
아키텍쳐
소프트웨어의 두 번째 가치는 software 라는 단어와 관련이 있다.
단어의 뜻 자체는 부드러운(soft)와 제품(ware)의 합성어이며, 제품은 상품(product)를 뜻하며
부드러운(soft)단어에 두 번째 가치가 존재한다.
소포트웨어를 만든 이유는 기계의 행위를 쉽게
변경할 수 있도록 하기 위해서다.
만약 이 행위를 바꾸는 일을 어렵게 만들고자 한다면 소프트웨어가 아니라 하드웨어 라고 불렸을 것이다.
소프트웨어가 가진 본연의 목적을 추구하려면 소프트웨어는 반드시 부드러워야 한다.
- 다시 말해서 변경하기 쉬워야 한다.
- 이해관계자가 기능에 대한 요구사항이 바뀌면 변경사항을 간단하고 쉽게 적용할 수 있어야 한다
- 이러한 변경사항을 적용하는 데 드는 어려움은 변경되는 범위(scope)에 비례해야 하며 형태(shape)와는 관련이 없어야 한다.
이런 토론을 했다.
상속을 줄이고, 확장하는 방식으로 개발을 하자는 이야기.
자바로 치면 extends를 줄이고 인터페이스를 implements 하여 확장하자는 식으로 나는 이해를 했다.
부모클래스의 스펙이 바뀌었다고 가정해보자.
부모클래스의 스펙이 바뀌면, 상속받은 모든 클래스들과 그 클래스를 이용하는 클래스들의 코드까지 다 바꾸어야 한다.
부모클래스 때문에 위에서 이야기 하는 범위(scope)가 엄청나게 넓어져 버린 것이다.
결과적으로 유지보수 하기가 어려워지고 개발 비용은 증가하게 된다.
이 문제를 해결하는 방법으로는 인터페이스를 사용하여 확장하면 훨씬 범위가 줄어들게 된다.
인터페이스를 사용할 경우에는 구현체만 갈아 끼우면 되는 경우가 많다.
다시 한번 고민해서 생각해보자.
문제는 시스템의 아키텍처이다.
아키텍처가 특정 형태를 다른 형태보다 선호하면 할 수록, 새로운 기능을 구조에 맞추는게 더힘들어진다.
- 책에서 이야기하는 형태는 스펙 보다는 디자인 패턴인것 같다.
아키텍처는 형태에 독립적이어야 하고, 그럴수록 더 실용적이다.
더 높은 가치
기능인가 아키텍처인가? 둘 중 어느것의 가치가 더 높은가?
소프트웨어가 동작하도록 만드는 것이 더 중요한가?
아니면 소프트웨어 시스템을 더 쉽게 변경할 수 있도록 하는 것이 중요한가?
업무 관리자에게 물어보면 동작하도록 만드는 것이 더 중요하다고 대다수가 대답할 것이고,
이어서 개발자에게 묻는다면 업무 관리자의 의견에 대체로 동조하는 태도를 취하게 된다.
- 왜 그럴까? 이해관계자들의 압박? 시장의 압박?
저자는 논리적으로 극단의 사례를 검토하는 방식으로 이 의견을 반박한다고 한다.
완벽하게 동작하지만 수정이 아에 불가능한 프로그램을 내게 준다면, 이프로그램은 요구사항이 변경될 때 동작하지 않게 되고, 결국 프로그램이 돌아가도록 만들 수 없게 된다.
- 따라서 이러한 프로그램은 거의 쓸모가 없다.
반대로, 동작은 하지 않지만, 변경이 쉬운 프로그램을 내게 준다면, 나는 프로그램이 돌아가도록 만들 수 있고, 변경사항이 발생하더라도 여전히 동작하도록 유지보할 수 있다.
- 따라서 이러한 프로그램은 앞으로도 계속 유용한 채로 남는다.
잘 생각해보자, 변경이 불가능하다. 구조가 너무 복잡하고 코드가 스파게티처럼 꼬여있다.
잘못 건드렸다간 컴파일도 안되고, 실행되더라도 런타임에 에러가 폭포처럼 계속 쏟아진다.
과연 나는 이 프로그램을 돌아가도록 만들 수 있을까?
반대로, 동작은 하지 않는다. 약간의 오류나 버그가 있다. 하지만 구조가 간단하고 코드도 클린하다.
내가 이해해서 고쳐서 쓸 수 있을것 같다. 변경사항이 발생했다.
나는 이 프로그램을 수정해서 동작할 수 있게 만들수 있다.
변경이 완전히 불가능한 프로그램이란 존재하지 않지만, 수정이 현실적으로 불가능한 시스템은 존재하기 마련이다.
변경에 드는 비용이 변경으로 창출되는 수익을 초과하는 경우에, 과연 이 프로그램을 변경하는것이 옳을까?
아이젠하워 매트릭스
드와이트 D. 아이젠하워 미국 대통령이 고안한 중요성과 긴급성에 관한 아이젠하워 매트릭스이다.
두 가지 유형의 문제가 있다. 긴급
, 중요
이걸 4가지로 경우를 쪼갠것이다.
- 중요하고 긴급함
- 중요하지만 긴급하진 않음
- 중요하진 않고 긴급함
- 중요하지도 않고 긴급하지도 않음.
긴급한 문제가 아주 중요한 문제일 경우는 드물고, 중요한 문제가 몹시 긴급한 경우는 거의 없다.
소프트웨어의 첫 번째 가치인 행위는 긴급하지만, 매번 높은 중요도를 가지지는 않는다.
소프트웨어의 두 번째 가치인 아키텍처는 중요하지만, 즉각적인 긴급성은 필요로 하는 경우는 절대 없다.
어떤 일은 긴급하면서도 중요할 수 있다.긴급하지도 않고 중요하지 조차 않은 일도 있다.
이들 네가지 경우에 우선순위를 매길 수 있다.
- 중요하고 긴급한 - 행위가 될 수 있다.
- 중요하지만 긴급하진 않음 - 아키텍처
- 긴급하지만 중요하지 않은 - 행위가 될 수 있따.
- 긴급하지만 중요하지도 않은
여기서 흔하게 저지르는 실 수는 세 번째 위치한 항목을 첫 번째로 격상시켜 버리는 것이다.
- 중요도의 구분을 명확히 해야 한다.
- 이 실수를 해버리면, 시스템에서 중요도가 더 높은 아키텍처를 무시한 채 중요도가 떨어지는 기능을 선택하게 된다.
업무 관리자는 보통 아키텍처의 중요성을 평가할 만한 능력을 겸비하지 못하기 떄문에 개발자는 딜레마에 빠진다.
소프트웨어 개발자는 이 딜레마를 해결해야 한다.
따라서 기능의 긴급성이 아닌 아키텍처의 중요성을 이해관계자들에게 설득하는 일은
소프트웨어 개발팀이 마땅히 책임져야 한다.
아키텍처를 위해 투쟁하라
회사에는 여러 팀이 있다. 이 팀들은 여러 이유로 각자 싸우고 투쟁한다.
개발팀은 회사에서 가장 중요하다고 스스로 믿는 가치를 위해 투쟁하고
관리팀, 마케팅팀, 영업팅, 운영팀 도 자신만의 가치를 위해 투쟁한다.
개발자들도 이해관계자인것을 명심해야 한다.
소프트웨어를 안전하게 보호해야할 책임
이 있다.
이것은 필히 개발자의 역할이며 책임이고 책무이다.
이 투쟁을 하지않으면 소프트웨어 개발팀에서 중요한것들의 중요도가 낮아진다.
명확한 논리로 투쟁을 하자! 개판치고 싸우라는 의미가 아니다!
하나만 기억하자.
아키텍처가 후순위가 되면 시스템을 개발하는 비용이 더 많이 들고, 일부 또는 전체 시스템에 변경을 가하는 일이 현실적으로 불가능해진다.
이러한 상황이 발생하도록 용납했따면, 결국 개발팀은 스스로 옳다고 믿는 가치를 위해 충분히 투쟁하지 않았다는 뜻이다.
'스터디 > 클린 아키텍처- 로버트마틴' 카테고리의 다른 글
클린 아키텍처 2부. (0) | 2022.09.04 |
---|