같이 교육을 받았던 프런트엔드 엔지니어 J의 사례와 연결된 이야기를 해보려 한다. 이 분은 여러  커뮤니티 활동을 하시는 것으로 보였다. 그중 하나의 커뮤니티에서는 참가자들의 만남을 이어주는 여러 이벤트가 있었다. 이 분은 이 만남과 관련된 자동화에 기여하시고 있었다. 이 기능은 Typescript 짠 코드였는데, 당시는 관리자와 본인의 컴퓨터에서 자동화 스크립트로서 동작하였다.

물론 잘 동작하는 코드였지만, 이 코드를 "적절한 설계 없이" 만들었다고 생각하신 듯했다. 그래서, 공유해 준 고민은 "좋은 구조로 만들고 싶다"였다. 나는 이러한 상황을 "구조가 없음"이라고 이해했다. 우리의 이야기는 "이 부분을 어떻게 개선하는가"가 포인트였고, 원 포인트 세션 논의를 통해서 개선 방향을 잡았다. 세션을 하고 난 얼마 후 이야기 나눌 때에도 계속해서 그 방향으로 발전시키고 계셨다. 모듈화를 하였고, 데이터를 원격에서 가져오는 작업, 서버에 스크립트를 채팅 어플의 봇(bot)으로 올리는 계획을 세우고 있었다.

하지만, 이 글에서 이야기하고 싶은 주제는 위에서 이야기한 개선 방향은 아니다. 그것보다는 우선 "구조가 없음"이라는 부분에 대해서 이야기를 해보고 싶다. 왜냐하면 많은 사람들이 간과하지만 "모든 소프트웨어에는 구조가 있기" 때문이다. 여기서 이야기하는 소프트웨어 구조는 동작하는 소프트웨어가 가지고 있는 구조에 대한 것이다. 즉, 개발자가 요구 사항에 따라 고민하고 구현하면 구조는 발생한다. 물론, 객체 지향 프로그래밍(OOP), 디자인 패턴(Design Pattern)과 같은 경험 많은 사람들이 찾아낸 내용들을 포함하는 것이 조금 더 좋을 수 있다. 하지만, 우리가 처리해야 하는 기능을 잘 처리하고 있고 동작하고 있다면 이미 "구조"를 가지게 되는 것이다. 그렇다면, 정말 좋지 않은 구조라면 의미가 없는 것일까?

여기서는 많은 사람들이 좋지 않다고 하지만 실제로는 많이 존재하는 구조 한 가지를 살펴보자. 큰 진흙뭉치(Big Ball of Mud)라고 부르는 구조이다. 이 구조는 소프트웨어가 모듈의 구분 없이 한 덩어리로 되어 있는 경우이다. 위에서 이야기 한 사례의 경우, 소스 코드는 유틸리티 기능을 제외한 코드가 하나로 되어 있었다. 그러므로, 큰 진흙뭉치에 해당한다고 할 수 있겠다. 기능이 동작하게 하는 것이 먼저 여서기 우선 필요한 기능들을 모두 모아서 구현했을 가능성이 높다. 기간도 부족하고 요구 사항도 불분명했을 가능성도 높다. 아마도 구현한 사람 이외에는 문제점을 수정하기 어려워 매우 낮은 유지보수성(maintainability)을 가질 것이다. 또한, 기능을 추가하거나 확장하는 것이 매우 어려워 확장성(extensibility)이 낮을 것이다.

그렇다면, 이러한 구조에서는 단점만 존재할까? 아니다, 이 구조의 장점을 주장하는 사람도 있다. 우선 이와 같이 작은 대상에 유리할 것이다. 이미 잘 동작하고 있고 적은 노력으로 동작하는 소프트웨어를 만들었다. 만일 이 기능이 상용 소프트웨어였다면 회사에서는 이 기능을 구현한 사람을 가능한 계속 채용한 상태로 유지하려고 할 것이다. 즉, 우스개 소리 같지만 개발자 입장에서는 고용이 안정될 수 있을 것이다. 나도 관련된 실제 사례를 들은 적이 있다. 이 사례의 경우는 통신 소프트웨어였다. 일반적으로 통신 소프트웨어에서는 계층화 되어, 레이어 1, 2, 3와 같이 주로 구분을 하는데 HW를 다루는 레이어 1의 경우는 보통 펌웨어로 다루는 경우가 많다. 그러다 보니, 레이어 1은 효율성이 강조가 되고 가독성과 같은 품질 속성은 많이 무시되는 경향이 있다. 이 전체 소프트웨어 개선을 목표로 여러 개발자들이 개선 작업을 한 것을 전해 들었는데, 레이어 2까지는 리팩터링을 했지만, 결국 레이어 1은 손대지 못하였다고 한다. 이 때, 레이어 1 개발팀은 계속 유지되고 있다고 들었다.

나는 애자일리스트로서 동작하는 소프트웨어를 더 존중한다. 그러면서도, 여러 가지 구조에 대해서 장단점이 있다고 생각한다. 심지어 큰 진흙 뭉치에서도 위에서 이야기한 것 같기 배울 점이 있다는 부분이 있다. 우리는 현실에서는 선택해야 한다. 동작하는 소프트웨어를 위해서 말이다.

들어가며

대부분의 사람들이 그렇듯이 자신의 역할이라는 것이 다양하게 있다. 누구의 자녀, 누구의 친구, 누구의 동료, 그리고 누구의 부모. 자신이 하고 있는 업 혹은 회사에서의 역할도 마찬가지다. 나도 그러한데, 이 여러 가지 중 조금 더 애착이 가는 것이 소프트웨어 아키텍트(Software Architect)이다. 나의 공식 직함은 관리자이다. 핸즈온 매니저를 계속하고 싶기는 하였지만, 현실은 그러지 못하고, 내가 필요한 도구 정도 코딩하고, 실제 제품에 포함되는 코드는 리뷰하기도 어려워진 것이 현실이다. 또한, 조금 더 개발자의 업무를 할 수 있는 것이 이 역할이기 때문이기도 하다. 그러면서, 회사 업무를 하며 실무 개발자들과 소프트웨어 아키텍처를 설계를 하는 것이 너무 귀한 기회이기도 하다.

최근에는 외부에서도 알게 된 분들과 함께한 아키텍처 관련 원 포인트 세션, 달리 말해 소프트웨어 문제점 멘토링으로 여러 사례들을 접하게 되었다. 흥미로운 것은 이러한 과정이 소프트웨어 아키텍트인 나에게도 큰 의미가 있지만, 소프트웨어 문제를 가지고 있는 분들에게도 실질적으로 도움이 된다는 사실이다.

우선 이론적으로는 도움을 요청하신 분들 입장에서는 첫 째, 소프트웨어 아키텍처 전문가를 데려다가 활용(How to bring experts)하는 측면에서 도움이 된다. 하지만, 이 부분에 맹점이 있다. 즉, 전문가와 일하되, 조율(Coordination)하고 통합(Integrate)하라는 연구[1]가 있다. 역서도 함정이 있는데, 비협업적으로 일하게 되면 비전문가들이 일하는 것보다 성과가 나쁘다는 내용도 언급되어 있는 것이 매우 흥미롭다. 또 다른 측면에서는 함께 같은 주제에 대해서 살펴보는 것이 페어 프로그래밍(Pair programming)과 같은 효과를 발휘한다. 이에 대한 이론적 배경으로 두 사람이 협력을 통한 추상화(Collaborative Abstraction)를 통해서 다른 시각(perspective)을 받아들일 수 있게 된다고 한다 [2]. 이 두 가지가 원 포인트 세션의 장점이라고 할 수 있겠다.

이와 같이 여러 사람들과 만나서 다양한 이야기를 듣게 되었고 다루는 내용이 현실의 소프트웨어 개발과 관련된 문제들이라는 생각이 들었다. 달리 말해 책에서만 존재하던 있던 내용들이 아니고, 우리가 살고 있는 실제 세상에 있었고 살아 있는 문제들이라는 생각이 들었다. 이 사례들들에 숨어 있는 이 이야기들을 끄집어내어서 내 생각을 조금 더 나누고자 한다.

 

참고 문헌

[1] A. W. Woolley, et al. "Bringing in the experts: How team composition and collaborative planning jointly shape analytic effectiveness." Small Group Research 39.3 (2008): 352-371.
[2] D. L. Schwartz, "The emergence of abstract representations in dyad problem solving", The journal of the learning sciences, 1995

이 책은 에디슨 위슬리 반 버논 시리즈의 여러 책 중의 한 권이다. 특히, 아키텍처 설계와 관련해서 관심을 가지다가 알게 되었고 번역 제안을 받아 진행하게 되었다. 쉽지 않은 과정이었지만, 몇 가지 알게 된 것, 느낀 것 그리고 번역에 대한 나의 짧은 생각을 적어 보려 한다. 

 

반 버논은 도메인 주도 설계(Domain Driven Design, DDD)가 도입되는데 큰 기여를 하고 있다. 특히, 도메인 주도 설계 구현(Implementing DDD)으로 유명하다. 나는 DDD가 요구사항과 구현 사이의 간극을 드라마틱하게 줄여주는 실천법이라고 생각한다. 이를 통해 확보한 요구 사항의 명확한 이해를 기반으로 효과적인 소프트웨어 설계를 수행할 수 있다. 흥미롭게도 비지니스 전문가와 개발자들이 함께 일하는 애자일 원칙과도 맞닿아 있다. 또한 이 책은 반 버논 시리즈의 두 번째 역서이다. 하나는 API 설계 원칙이다. 반 버논의 추천사를 보아도 두 책의 저자들이 상호 보완적으로 글을 썼다고 한다. 이 책에서는 웹 API 설계 원칙의 정렬-정의-설계-구체(Align-Define-Design-Refine) 단계 개념을 패턴에 적용하기도 했다.

 

반버논의 추천사에서 보면 유기적 구체(organic refinement)는 소프트웨어와 관련된 모든 개념이 무생물이 생물체의 측면을 '특성화'한다는 아이디어를 언급한다. 소프트웨어는 구체적인 시나리오를 통해 모델을 논의하거나 아키텍처를 설계하고 단위 테스트와 도메인 모델을 작성함으로써 살아 움직이기 시작한다. 마찬가지로, 건축가이자 패턴 개념을 만든 크리스토퍼 알렉산더는 "Nature of Order"에서 인간 배아(Embryo)의 예를 들며, 분화(Differentiation)에 대해 이야기한다. 이는 유기적 구체와 매우 유사하며 유기적이며 발전하고 성장하는 프로세스를 강조한다. 이러한 관점에서 소프트웨어의 진화는 생물의 발전에 대한 이해와 유사한 맥락에서 이해할 수 있다. 생명체가 환경과 상호작용하면서 성장하고 변화하는 것처럼, 소프트웨어도 사용자와 시스템 사이의 상호작용 속에서 점진적으로 발전하는 것이라 이해할 수 있다.

 

이 책에서 언급하는 패턴의 경우도, 이러한 유기적 구체 혹은 분화 과정에서 발견되는 반복적인 내용들을 잡아 내어 패턴의 커뮤니티에서 키워내고 리뷰하여 만들어 내는 과정을 거친다. 그러므로, 패턴, 유기적 구체, 분화와 같은 것을 이해하고 소프트웨어 구조를 설계할 때 분화의 관점 그리고 소프트웨어가 발전 성장하는 과정에서 패턴을 적용해가는 것이 필요하다는 관점에서 이 책에 접근하는 것을 권한다.

 

개별 언어는 독특한 여러 특징을 가진다. 이로 인해, 각 언어에 내재한 작은 뉘앙스 차이를 다른 언어로 옮기는 일은 매우 어렵다고 생각한다. 이 책에서는 "force"라는 어찌 보면 ""이라고 단순하게 번역할 수 있는 단어의 번역에 고민을 오래 하였다. 소프트웨어 설계에서 "force"는 설계 결정에 영향을 미치는 다양한 요인을 의미한다. 특히 이 책에서는 패턴의 문제-해결 짝과 이후에 상세 설명에서 패턴과 관련된 여러 "중요한 요구 사항"을 가리키는 용어로 등장한다. 이는 서로 상충되는 경우가 많다. 다른 아키텍처 책에서도 이 "force"를 언급하지만 이 책에서 더 자주 언급되어 시간을 들여 고민을 하였다.

 

이 책에서는 한글과 원어를 여러 번 병기하였다. 그 이유는 소프트웨어 개발이나 소프트웨어 개발과 관련된 도메인의 중심이 여전히 미국에 있기 때문이다. 따라서 영어로 쓴 원서나 관련 논문, 인터넷 글을 읽을 기회가 많으므로 원어 용어에 익숙해져야 한다. 따라서 이 책에서도 병기를 충분히 했다. 여러분도 책을 보면서 소프트웨어 아키텍처와 소프트웨어 개발에 관련된 원어 용어에 익숙해졌으면 한다.

 

번역 중 저자들과의 몇 번의 소통이 있었다. 올라프 짐머만과의 몇차례 이메일을 통해서 사소한 오탈자 뿐 아니라 그들이 생각하는 용어 정의와 같은 부분에 대해서도 의견을 나눌 수 있었다. 이러한 과정은 나에게 새로운 경험이었고, 책에 담긴 내용을 조금 더 깊게 이해하는데 도움이 되었다.

 

책의 번역을 마무리하면서 소프트웨어 개발, 설계에 대해 다시금 돌아보며 좋은 학습의 기회였고, 저자와 연락하며 짧지만 전문가들과 이야기 나눌 수 있어서 좋았다. 번역이라는 작업에 대해서도 내 생각을 정리하는 것은 나름 의미가 있었다

+ Recent posts