안녕하세요! 보노입니다.
아주 오랜만에 포스팅을 하게 되었습니다.
본 포스팅은 최근 진행한 미니 프로젝트에서 기획자
, 디자이너
, 개발자
를 대상으로
1) 제가 이해한 개발자의 책임에 대해 나누고
이를 토대로 2) 프로젝트 구조 설계를 제시한 발표
내용 입니다.
발표 당시의 제목은
모두가 이해한 프로젝트
였습니다.
포스팅을 작성하며 보다 내용을 명확히 하기 위해 iOS 개발자가 서비스에 가지는 책임으로 제목을 변경하였습니다.
본문에 들어가기 앞서, iOS 개발자의 책임은 무엇일까요?
개인적인 깨달음을 담은 글이니 가볍게 읽어주시면 좋을 것 같습니다.
(본 포스팅은 본문도 길지만 서론도 몹시 긴 글이 될 것 같습니다..!)
과거에 저는 개발자가 가지는 책임에 대한 이해가 없어 방대한 지식을 무작위로 접하였습니다.
Swift 문법, CS, 알고리즘,
UIKit, SwiftUI, MVC, MVVM-C, Ribs, TCA 등의 아키텍처 방법론들, 모듈화, Tuist, RxSwift, Combine, 객체지향 프로그래밍, 함수형 프로그래밍과 같은 것들 말입니다.
수많은 지식에 대한 학습은 추가적인 학습을 필요로 했고, 어디까지 공부해야 하는 건지 몰라 스스로를 절망과 혼란에 빠뜨렸습니다.
점점 서비스 구현과 학습은 별개의 영역이 되어갔습니다.
그러니
아키텍처에 대한 학습은 3년 차 이하가 필요를 느끼기 어려운 영역인 것 같다
며 한탄하기도 했습니다.
(이에 대한 생각이 어떻게 바뀌었는 지는 별도의 포스팅으로 마련하고자 합니다)
그렇게 헛도는 느낌을 안고 개발을 지속하던 어느 날, 클린 아키텍처
를 읽다가 제가 개발자의 역할에 대해 오해하고 있던 지점을 벼락치듯 깨닫게 되었습니다.
깨달음을 준 문장은 아래와 같습니다.
소프트웨어 개발자인 당신도 이해관계자임을 명심하라. 당신은 소프트웨어를 안전하게 보호해야 할 책임이 있으므로 당신 역시도 이해관계가 있다. 당신의 역할 중 하나며, 당신의 책무 중 하나다.
소프트웨어를 안전하게 지킬 책임이 있음을 강조하는 문장이었으나, 제게 주는 울림은 좀 더 본질적인 것이었습니다.
왜 개발자가 서비스를 위하는 입장임을 놓치고 있었지?
스스로 질문하자 답답하게 느꼈던 모든 것들이 엮이고 풀리는 것을 느꼈습니다.
여러 기술적인 논의, 아키텍처, 학습의 필요를 진정으로 느낌과 동시에 협업, 커뮤니케이션을 강조하는 이유에 대해서도 단숨에 이해할 수 있었습니다.
지난 협업 과정에서 개발자의 책임을 다하고 있지 못했구나 반성하며 학습 방향을 점검하기도 했습니다.
구현과 학습을 별개로 가져가는 것에는 변함이 없지만,
무엇을 위해 학습하는가에 대한 이해가 생기니 더 이상 모든 학습이 막연하지 않았습니다.
더 나아가 협업에 임하는 태도도 바뀐 것을 느낄 수 있었습니다.
디자인에 공부를 시작한 것도 개발자의 책임에 대해 고민한 이후의 변화라고 볼 수 있을 것 같습니다.
본 발표는 팀원들에게 개발자의 책임에 대해 전하는 것이 가장 큰 목적이었습니다.
그를 통해,
1) 공동의 목표를 점검하여 개발 단계에서 각 파트간 건강한 커뮤니케이션 문화를 구축하고
(어려워서 안돼요. 와 같은 개발자 갑질 방지)
2) 프로젝트 설계의 필요를 설득 하여
3) 서비스를 위하는 개발 논의를 이끌고자 했습니다.
더 나아가 최종적이고 개인적인 목표는
개발자의 고민이 그리 막연한 것이 아님을 전하여
파트에 관계 없이 모든 팀원들이 개발에 참여하도록 하는 것 이었습니다.
(개발 직군이 아닌 팀원들도 개발에 대한 열정이 있는 상황이었기 때문에 생긴 욕심이었습니다)
발표의 내용을 요약하자면 아래와 같습니다.
과거 배움을 얻을 수 있는 곳에서 일하고 싶다 생각했습니다.
제가 가진 논의점들에 해답을 제시하는 집단에 소속되고 싶어 열심히 공부했습니다.
하지만 이제는 어딜 가도 건강하게 교류하는 사람이 되고 싶습니다.
습득한 지식이 있다면 그 필요를 모르는 팀원에게 그를 설득할 수 있는 팀원이 되고 싶어 공부하게 됩니다.
본 발표는 제가 가진 개발자에 대한 이해를 전달하고, 개발 경험이 없는 팀원에게도 설계의 필요 전달 합니다.
제가 가진 지식의 필요를 설득시킬 수 있는 지 검증하는 자리였습니다.
결과적으로, 해당 발표를 들은 팀원들은 전부 개발에 참여하였습니다.
모든 팀원들이 개발에 참여하여 개발자로서 고민하고 개발자로서 개발의 재미를 느끼고 논의하여 MVP 개발을 끝마쳤습니다.
이 포스팅을 열정적인 팀원들, 개발자로서 걷고자 하는 길이 옳음을 확신하게 만들어준,
고스트
,구름
,로셸
,브리
,에디
에게 바칩니다!
피드백이나 궁금한 점 남겨주시면 감사히 읽겠습니다!
감사합니다!
(아래부터의 본문은 팀원들에게 발표한 발표 내용에 해당합니다)
우리 팀은 기획자 2
, 디자이너 2
, 개발자 2
로 이루어졌다.
그리고 모두가 파트에 대한 엄밀한 구분 없이 기획, 디자인 과정에 참여했다.
기획을 시작으로 도메인이 결정되자 디자인을 시작했고, High-Fi가 완성되자 MVP를 목표로 개발에 들어섰다.
수시로 우리의 논의에 사용자가 고려되고 있는 지, 해당 디자인이 우리 앱의 도메인을 해치지는 않는 지 점검했다.
하지만 모든 팀원들이 개발을 앞두곤 전혀 다른 영역에 들어선 듯 막연함을 느꼈다.
더 나아가 기획자와 디자이너가 서비스를 잘 만들기 위해 하는 노력
을 이해하던 것과 달리
개발자가 서비스를 잘 만들기 위해 하는 노력
은 가늠하지 못했다.
그러니 개발이 도메인에서 벗어나고 있지는 않은 지 질문하고 논의할 힘을 잃었다.
기획자나 디자이너, 개발자 모두 서비스를 잘 만들고자
노력한다는 점에서 같은 선상에 있다고 생각한다.
그렇다면 개발자가 서비스를
잘 만들고자
하는 시도란 무엇일까?
기획자, 디자이너, 개발자는 서비스의 이해 관계자이다.
서비스를 이해하며, 잘 되게 하기 위해 노력한다.
하지만 개발자가 서비스를 위하는 방식은 종종 기획자 디자이너에게 서비스에서 동떨어진 것으로 추측되곤 한다다. 때론 개발자 또한 서비스를 위하는 노력과 개발, 구현을 분리하여 이해한다.
코드를 통해 서비스를 잘 만들고자 한 시도를 직관적으로 이해하기 어렵기 때문이다.
특히나 iOS 개발자라면 디자인을 토대로 화면을 구현하는 일이 중요하게 여겨지니,
개발자가 디자인의 후발 주자로서 디자인을 구현하는 역할이라 판단될 여지가 많은 것 같다.
바로 이러한 점이 개발자의 역할을 뷰에 한정시켜 전체적인 프로젝트 코드가 무엇을 위하는 지 혼동되게 만든다.
물론, iOS 개발자에게 화면을 만들고 매끄러운 사용감을 제공하는 일은 거의 전부라고 느껴질 만큼 업무의 대부분을 차지하는 일이다.
하지만 뷰 구현이 무엇을 위해 진행되는 일인지 이해하여야 한다.
그렇지 않으면 개발자는 곧 뷰 구현자가 되어 서비스의 이해 관계자로서 역할을 이해할 수 없게 된다.
마치 iOS 개발자가 뷰를 위한 개발자라고 착각하게 만든다.
서비스 이해 관계자라는 표현을 자주 언급하는 이유는, 기획, 디자인, 개발 전부가 공동의 목표를 가진다는 점을 강조하기 위함이다.
서비스를 위하는 목표, 서비스의 정체성인 도메인을 잘
만들고자 하는 시도가 바로 그것이다.
모든 팀원들은 서비스를 잘
만들기 위해 고민한다. 서비스를 잘
만들기 위해 결정한 뷰에 개발자의 역할을 한정지으면 개발자는 디자이너의 후속주자로 이해되기 쉽다.
개발자는 디자인의 후속 주자가 아닌, 도메인을 잘 만들기 위해 노력하는 서비스의 이해 관계자이다.
개발자는 기획자, 디자이너와 공통의 도메인을 공유하고 그를 잘 만들기 위해 여러가지 합리적 판단을 거친다. 더 나아가 서비스 과정에서 변하기도 하는 유즈케이스, 화면 등에 대비하기 위해 코드 생태를 유연하게 만들고자 노력한다. 기능 추가 상황에 대비하는 것 또한 마찬가지다.
개발자는 빈번하게 변하는 구체적 결정들 속에 도메인을 지키고 갈아끼우는 역할을 수행한다.
개발자의 책임은 도메인을 잘
만들자 이다.
자유로운 시도를 위해선 기초가 필요하다. 선택할 수 있는 도구의 수
를 늘리기 위해선 새로운 기술 학습이 필요하다.
하지만 여전히 도메인을 잘
만들자란 말 만으론 개발자가 실제로 고민하는 부분을 상상하기 어렵다.
개발자의 입장에서 도메인을 잘 만든다는 것은 어떤 고민을 의미할까?
우선 Domain이란 무엇일까. 해당 키워드는 서술 상황에 따라 묘사되는 범위에 차이가 있는 것 같다.
그러니 현재의 발표에서는 Domain을
서비스 이해 관계자 모두가 공유하고 있는 앱의 컨셉, 정체성
이라고 정의하자.
본 발표에서 등장하는 키워드가 타 자료에서 언급되는 키워드와 다른 맥락을 지닐 수 있음을 경고하고 싶다.
하지만 대게 개발자 월드 속 키워드가 그런 것 같다.
어떤 방식으로든 이해했다면, 앞으로 구체화 해 나가면 된다 생각한다. 그러니 너그러운 마음으로, 가볍게 봐 주었으면 한다.
Domain에는 사용자가 서비스와 어떻게 교류하길 바라는 지에 대한 UseCase
와, 시스템에서 다루는 주요 개체나 개념을 의미하는 Entity
가 존재한다.
서비스 이해관계자라면 모두가 이해하고 공유하는 내용이다.
즉, 개발자만 아는 키워드로 묘사되는 것이 아니라, 모두가 알고 있는 추상적인 내용들로 구성된 것들을 말한다.
구체적인 예시로 알아보자.
우리 서비스의 경우 세 가지의 UseCase로 Domain을 분류할 수 있다.
이 중 기록UseCase
란 무엇이고 이를 만들기 위해 어떠한 결정이 필요될까.
기록UseCase
는 사용자가 야구 경기의 다양한 기록을 입력하고 저장하며, 이를 실시간으로 화면에 표시하는 과정을 말한다. 이러한 과정은 사용자에게 최신 경기 정보를 제공하고, 기록
을 체계적으로 관리할 수 있도록 도와준다.
기록
과정에는 어떠한 정보가 필요한 지 알아야 한다. (Entity)
Entity는 서비스 이해 관계자 모두가 알고있는 앱의 다양한 주제 정보를 말한다.
여기까지는 기획자, 디자인, 개발자 모두가 공유하고 있는 절대적인 앱의 정체성 이자 Domain 영역에 해당하는 내용이다.
구체적인 방법은 없고, 추상적인 내용이라 코드 상에선 추상적 계층
, 또는 고수준
이라 부른다.
개발자는 해당 도메인을 구현하기 위해 구체적인 수단
, 즉 구현 계층, 저수준을 구현해야 한다.
무엇이 우리 앱에 적합하고 합리적인 선택일까?
이러한 선택 사항에 대한 적절한 고민은 코드에 대한 이해를 필요로 하고, 이 시점부터는 기획자와 디자이너에게는 낯선 용어가 등장한다.
그러나 여전히 Domain은 모두가 알고 있는, 공통적인 내용이다.
기록UseCase
에서 선택해야 하는 저수준 결정은 두 가지이다.
바로 이를 표시할 화면 구성 방식(View)과 저장하는 방식(Data)의 결정이다.
개발자는 Domain을 구현할 수단으로 구체적인 방법을 선택해야 한다.
iOS 개발에서는 View와 Data 저장 방식을 구현할 다양한 수단이 있다.
대표적인 화면 구현 수단으로는 UIKit
과 SwiftUI
Data 저장 수단으로는 CoreData
, SwiftData
, Server 통신
등이 있다.
중요한 것은, 이 모든 것들이 도메인을 구현하기 위한 구체적인 수단에 해당한다는 점이다.
우리 팀은 View(입력 인지, 표시)와 Data(저장, 불러오기)를 구현하기 위해 SwiftUI와 CoreData를 선택하였다. (이유에 대한 논의는 해당 포스팅에서 생략한다. 각각은 학습 접근성과 팀원들의 학습 의지에 따라 선택되었다)
View는 Domain에서 하드웨어와 사용자의 인터렉션 상황을 알기 위해 필요한 구현체다.
UseCase
에게 사용자 액션을 전달하고, UseCase
의 의도를 따라 변경된 Entity
값을 보여주기 위해 서 필요한 존재이다.
우리는 View에서 어떻게 전달받고 응답할 것인지에 대해 구체적으로 명시한다.
View
는Domain
의 필요에 의해 선택됐다. 그러니 View가 Domain에 직접적으로 영향을 행사하는 상황은 논리적으로 이상하게 느껴진다.
그러나 코드는 유기적으로 맞물려 돌아가기에 View에서의 변화가 Domain 코드에 영향을 미칠 수도 있다.
디자이너가 잘못된 디자인이 사용자에게 Domain의 내용을 착각하게 만들지 않도록 경계하듯이,
개발자는 View의 구현이 Domain을 변경시키는 일을 경계해야 한다.
즉, 개발자는 코드 수준에서 구체적 구현 계층이 앱의 도메인을 침범하지 못하도록 관리할 필요를 느낀다.
데이터 저장, 갱신 수단 또한 마찬가지다.
기획자, 디자이너는 개발자가 어떤 방식으로 Data를 저장하고 불러올 건지에 대해 정확히 알지 못한다.
CoreData라는 명칭도, SwiftData라는 명칭도 모른다.
(하지만 여전히 저장한 뒤 불러오자는 논의를 나눈다.
저장한다
는 말 자체는 몹시도 추상적인, 도메인 영역에서의 논의이기 때문이다)
개발자는 우리 서비스에 적합한 데이터 저장 수단이 무엇일지 고민하게 된다.
더 나아가, CoreData를 통해 데이터를 저장하겠다는 결정이 Domain을 침범하여 변경할 수 없도록 의식한다.
(이를 해결하는 대표적인 방법으로, 인터페이스를 두어 의존을 분리하는 방법이 있다)
(Domain->Data는 대표적인 고->저 의존이다)
(그러나 개발자는 때때로 View->Data와 같은 저->고의 상황에서도 의존을 분리하고자 시도한다.) (설계를 제시하는 본문에서 추가적으로 언급될 내용이다)
개발자는 여러가지 사항을 염두에 두며 궁극적으로 Usecase
가 가진 시나리오에 해당하는 구현체를 작성하고 적절히 연결한다.
모든 노력은 소프트웨어가 변경에 유연하도록, Domain을 잘 만들기 위해 노력하는 개발자의 방식이다.
해당 내용을 통해 Domain이라는 폴더 구조가 필요하다고 말하고 싶은 것은 아니다.
이러한 내용이 .swift 파일 내부에 전부 들어있을 수도 있다. 하나의 ContentView 위에 들어있고 이러한 코드가 이해하기 쉽다고 주장하는 것이 타당할 수도 있다.
위의 구분(Domain, View, Data)은 서비스에 따라, 개발자에 따라 어떠한 방식으로 분류되고 구현될 지 모른다.
전하고 싶었던 것은 그저 서비스의 Domain에 대한 구체적 구현으로서
View
와Data
가 결정된다는 것 뿐이다.
이제 코드를 작성할 때 View를 작성하고, Domain을 작성하고,
Data를 작성하는 상황이 프로젝트 구조의 어디쯤에 위치하고 있는 지 상상할 수 있다.
코드 속에서 길을 잃지 않을 수 있다. 무엇을 위한 코드인 지 알고 작성할 수 있다.
물론, 알고 있더라도 여전히 길을 잃기도 한다.
그를 방지하기 위해선 더 많은 논의와 뒷받침할 지식들이 필요하다.
길을 잃지 않기 위한 고려들은 경험적
으로 부딪히며 늘기도 하고, 꾸준한 학습
을 통해서 늘기도 한다.
어떠한 방식이 되었건, 모든 학습은 서비스를 위한 일이다.
View와 Data 계층이 Domain 계층의 필요에 의해 생성되었음을 명확히 하기 위해 UseCase
가 View
에 반영될 상태값(State
)과 액션(Action
)을 전부 가진 프로젝트 설계를 제안하고 싶다.
더불어 UseCase
가 Data 계층을 직접적으로 의존하지 못하도록 그 사이에 인터페이스를 두어 Domain의 독립성을 보장하도록 만들자.
이러한 설계를 통해 아래를 기대할 수 있다.
1) View에 변동을 야기하는 상태의 출처를 UseCase 내부로 고정하여 복잡한 로직 속에서 예기치 않는 상태 변동을 방지할 수 있음
2) Data 구현체가 만들어지기 전에도 UseCase 내부 로직을 완성할 수 있음
=> 내 코드로 인해 망가지지 않는 프로젝트 구현
=> 원인 추론이 용이한 프로젝트 구조
(아키텍처 방법론 중 MVI와 TCA의 지향점을 일부 참고하였다)
(앞선 논의를 따르기 위해 앞으로 설명할 구조를 반드시 따라야 한다는 뜻은 아니다!)
해당 설계가 어떤식으로 동작하는 지, 구체적인 이해를 돕기 위해 이미지를 살펴보자.
View
는 UseCase
가 필요로 하는 사용자 액션을 UseCase
의 메서드를 통해 전달한다. (실행한다)
UseCase
는 해당 상황, 메서드가 실행될 상황에 적절히 상태를 변경한다. 그러한 상태 변경은 View
에 적용된다.
우리의 설계에서 View
는 본인이 실행한 UseCase의 메서드
가 어떠한 상태 변동을 만들어 내는 지 알지 못한다. 메서드를 실행하고, 상태가 변동된다면 반응할 뿐이다.
View
를 바보 만든다-는 표현은 이러한 상황에서 쓰인다
Domain
은 때때로 View
에 의해 실행되는 Action(메서드)의 동작으로 Data
에게 CRUD를 요청해야 한다.
이를 요청하기 위해서는 UseCase 내부
에서 Data
를 저장하는 객체(구체적인 구현체)에 대한 정보를 알고 있어야 한다.
우리는 고수준이 저수준에 의존하는 것이 불안정함을 이해하였에,
Domain
과 Data
사이에 Interface
를 두고자 한다.
Domain(UseCase)
은 Data
의 구체적인 타입에 의존하지 않고 필요한 메서드
만 바라볼 수 있게 된다.
(인터페이스
는 프로토콜
또는 정적 메서드
로 구현할 수 있다)
그러니 코드작성에 실질적 구현 객체를 몰라도 된다.
(해당 설계를 토대로 실제로 우리 프로젝트는 도메인이 먼저 작성되고, 구체적인 Data 저장 객체가 후에 개발되었다)
그저 UseCase
는 DataInterface타입
을 가지고 필요한 로직을 작성한다.
해당 로직의 구체적 구현체가 결정되는 순간은 UseCase가 생성되는 상황으로, 주입하면 된다.
실제 프로그램이 실행될 때의 의존과 (런타임 의존) 코드가 바라보고 있는 대상이 (컴파일 의존) 서로 다른 방향을 향한다.
각 계층 간의 분리를 이루기 위해 사용하는 해당 방식을 의존성 역전
이라 한다. 고수준 코드가 저수준 코드를 직접적으로 알지 못하게 하기 위해 사용되는 방식이다.
(우리 팀 프로젝트는 단일 타겟으로 개발되어 고려하지 않았지만, 모듈화
를 이루려면 (독립 빌드) 소스코드 간 의존성을 끊어내기 위해 의존성 역전을 필수적으로 고려해야 한다)
의존
이라는 말 뜻 그대로 바라보면 의존성에 대한 이해가 편한 것 같다.
기존에 UseCase
는 구체적인 Data 코드
를 의존
하고 있기에, Data 코드
로 부터 자유로울 수가 없다.
UseCase
가 동작하기 위해선 Data 코드
를 사용해야하기, 필요하기 때문이다.
하지만 Interface
를 둔 순간 UseCase
는 더 이상 실제 Data 구현체
를 직접적으로 알지 않아도 된다.
의존하지 않으니, 영향을 받지도 않는다.
의존하고 있는 인터페이스의 메서드가 누구로부터 구현되었는 지는 프로젝트가 실행될 때 (런타임) 알게 될 것이다.
저수준
(구체적 구현체)는 고수준
의 필요에 의해 탄생하였으니 저수준
이 고수준
을 알고 있는 상황이 이상하게 느껴지지 않는다. (View
-> Domain
상황을 말한다)
하지만 실제 프로젝트 설계에는 View
가 Domain
을 소유하여 접근하는 상황 자체가 종종 불편하게 여겨진다.
사실 실제 프로젝트 중에는 서비스 이해관계자의 논의를 통해 Usecase가 변경되기도 하기 때문이다.
자연히 개발자는 UseCase
의 변경 또한 View
에 큰 영향을 미치지 않길 바란다.
이러한 필요로 인해 개발자는 저
-> 고
로 가는 길목에도 인터페이스
를 둘 수 있다.
이를 통해 저수준
이 고수준
을 의존하는 상황도 소스코드 상으로 완전히 끊어낼 수 있게 된다.
우리의 서비스에서는 View
와 Domain
사이 인터페이스 계층의 필요를 직접적으로 느끼기 어렵다고 판단되어 고려하지 않았다
즉, Domain
-> Data
사이에만 Interface
가 존재한다.
앞선 구조를 위해 위와 같은 폴더링을 가져가고자 한다.
App
은 우리 앱이 구동될 때 실행될 앱의 첫 시작 뷰를 담고 있다.
DesignSystem
은 공통으로 사용될 우리 앱의 디자인 설정 또는 컴포넌트를 담는다.
Data
, Domain
, Screens
는 앞단에서 나눈 세 개의 계층을 의미한다.
View가 아닌 Screens라 표기한 이유는 View가 아닌 조합된 하나의 화면을 의미하기 위해서 이다.
구체적으로 어떻게 작성할 지에 대한 발표 내용은 생략하고자 한다.
혹시 몰라 아래엔 이해를 돕기 위해 MVP 작업 이후의 코드를 간략히 첨부한다.
(* 폴더 분류 및 코드 관련 내용은 MVP 개발이 끝난 시점 붙여 놓은 이미지 입니다)
때때로 아키텍처 구조에 대해 고민하고 설계하는 일,
프로그램을 유연하게 만들기 위해 다양한 방법론에 대해 접하고 학습하는 일은 유지보수
에서만 유용한 일로 치부되곤 한다.
하지만 우리는 단순 구현 상황에서도 수많은 변경과 고민을 거친다.
앞선 아키텍처 설계처럼 커다란 컴포넌트 간 구조건
, 객체와 객체간의 관계건
, 함수와 함수간의 관계건
,
계층 간 중요도를 가늠하고 변경에 대해 대비하는 자세는 언제 적용해도 가장 빠른 길을 제시한다.
개발자의 노력이란 결국 서비스를 위한 노력이고 서비스를 안전하고 빠르게 발전시키기 위한 책임이다.
다양한 기술 학습 또한 더 나은 방식을 위해 고민할 선택지를 넓히기 위함이다.
본문에선 개발자의 책임을 아키텍처에 대한 논의로 엮어냈다.
이 외에도 개발자가 서비스를 잘
만들기 위해선 수 많은 고려사항들이 존재한다.
개발자는 기획자, 디자이너와 계속해서 대화해야 한다.
타 파트의 의견을 적극적으로 수용하고 때로는 타 파트의 의견으로부터 우리 서비스를 지켜야 한다.
그것이 서비스를 위하는 태도이기 때문이다.
화면 구현은 개발자가 서비스를 잘 만들기 위해 책임지는 영역 중 하나일 뿐이다.
본질적인 책임은 서비스
잘
만들고 운영해 나가는 것에 있다.
(개발을 처음하는 팀원의 즐거운 PR!)
약 2주라는 짧은 개발 기간임에도 팀원들은 MVP 제작을 성공적으로 끝마쳤습니다.
6명의 모두 개발 경험에 관계 없이 참여하였으며 모두가 컨트리뷰터로 이름을 올렸습니다.
가장 기뻤던 피드백 중 하나는
왜 문법공부를 해야하는 지 알겠다-
였습니다.
저의 팀원은 제가 과거에 겪었던 왜 해야하는가에 관한 고난을 겪지 않고 이정표를 지닌 채 학습해 나갈 수 있다면 좋겠습니다!
가진 지식을 타인에게 이해시킬 수 없다면 그 지식의 효용 가치를 재고해야 한다 생각합니다. 개발 경험이 없는 분들께서도 필요를 이해할 수 있도록 전달하는 것은 제게 있어 도전이었습니다.
코드 속에서 길을 잃지 않으려면, 내가 작성하는 코드가 어떠한 이유로 존재하는 지 머릿 속에 그려볼 수 있어야 한다 생각합니다. 그를 그리는 힘을 얻는 포스팅이었다면 좋겠습니다.
우리 팀 최고!
"습득한 지식이 있다면 그 필요를 모르는 팀원에게 이를 설득할 수 있는 팀원이 되고 싶어 공부하게 됩니다."라는 부분이 특히 와닿습니다.
저는 주로 백엔드 개발을 하고 있어서 iOS 에서 뷰 만드는 것에 대한 지식과 공감이 부족하지만 막연하게 단순 DB 데이터 서빙을 하는 백엔드를 만드는 것과 비슷하다고 생각하면 "개발자는 곧 뷰 구현자가 되어 서비스의 이해관계자로서 역할을 이해할 수 없게 된다."는 내용이 아주 큰 공감이 됩니다.
저는 개발할 때 도메인은 "실제 문제를 다루는 영역"으로 취급합니다. "해당 분야 전문지식을 코드로 구현하는 것"으로도 생각하구요. 그리고 그 핵심 코어 로직들을 엔드 포인트와 DB에 연결하는 걸 서비스 영역 혹은 애플리케이션 영역이라고 얘기하구요
저는 요즘 일하면서 개발자는 기획자보다 도메인을 더더더더더더 잘아야 한다고 느끼고 있어요. 같은 서비스를 만드는 사람들이라면 다같이 코어(도메인) 개발에 적극적으로 참여해야 하는 게 맞는다고 생각합니다!
그걸 실제로 같은 팀에서 실행한 보노님 대단하십니다. 좋은 글 잘 읽었습니다!
“기획자, 디자이너, 개발자 모두 서비스의 이해관계자이다.”
너무 좋고, 중요한 말인 것 같습니다! 결국 하나의 목표를 위해 나아가고 있다는 것과 동시에 본질적으로 다르지 않음을 명확히 해주는 문장이었습니다.
디자이너로 업무를 진행할 때도(도메인을 잘 만들기 위해) 고민했었던 지점들이 너무나 당연하게도 개발할 때도 적용하기 위해 노력해야 함을 알 수 있었습니다.
또 이 같은 이해를 팀원들과 공유했을 때 기대할 수 있는 효과도 상상 그 이상일 수 있겠다는 생각도 들었습니다.
모두가 같은 곳을 바라볼 수 있을 때, 서로의 업무가 무엇을 위하고 있는지 명확히 알 수 있을 때 얻는 시너지는 제가 바라던 이상적인 팀의 모습이었던 것 같습니다.
보노님의 생각을 이렇게라도 볼 수 있음에 진심으로 감사하고 소중하네요! 너무 잘 읽었습니다!! 🦦
이 글을 읽으며 가장 와 닿았던 부분은 학습의 목적이었습니다.
저는 길지 않은 시간 동안 개발에 대해 공부해 왔고, 이는 뚜렷한 목적이 없이 언제나 ‘추후에 사용할 수 있기에’라는 분명하지 못한 이유를 달고 있었던 것 같아요. 본문에 있는 말처럼, 개발을 ‘디자인을 구현하기 위한 수단’ 정도로 생각하고 개발에 임해 왔고, 이러한 부분이 제가 개발을 하는 데 있어 목적성을 흐리게 하고 흥미의 발생을 막고 있던 건 아닐까 싶습니다.
하지만 보노의 글을 읽고, 개발의 목적과 개발자가 서비스를 잘 만들기 위해 하는 노력 등에 대해 이해할 수 있게 되었어요. 사실 이 글을 읽기 전 보노가 팀원들을 위해 이야기해 준 덕분에 미리 느낄 수 있었습니다. 단순히 설명을 듣는 것보다 함께 개발을 진행하며 이러한 내용이 보다 더 잘 와닿았던 것도 같고요. 하지만 보노의 글이 없었다면 이 글을 전부 읽은 지금 이 시점과 같이 매끄러운 연결을 가질 수 없었을 것이라고 확신합니다.
보노가 여러 번 강조해 준, [View와 Data는 Domain을 구현하기 위한 수단]이라는 말 또한 이번 기회를 통해 다시금 뚜렷하게 이해하게 되었습니다. 몇 번의 프로젝트를 거쳐 오는 동안 SwiftUI를 선택한 이유는 어쩌면 스유를 사용하는 것이 당연하기 때문이었고, 데이터 저장을 시도할 당시 CoreData가 아닌 SwiftData를 선택했던 것도 단순히 최신 기술이기 때문이었습니다. 내가 기획한 서비스를 위한 수단임을 인식하지 못하고 있었기에 그간 그들을 사용하기 위한 서비스를 기획하고 끼워 맞춘 게 아닐까 하는 생각이 이제서야 들었어요. 이 부분은 정말 중요한 가치인 것 같습니다. 뷰와 데이터가 도메인의 구현 수단이라는 점을 인식하는 것은 서비스를 위하는 개발의 시작이며, 개발을 더욱 풍성하게 만들어 주는 기반이 되어주리라 생각합니다.
다른 사람들에게 자신이 가지고 있는 지식을 나누어 주는 건 언제 생각해도 쉽지 않은 일인 것 같습니다. 그런 점에 있어서도 보노는 정말 멋있는 사람이라고 생각해요. 나의 이해에서 끝나는 것이 아닌 다른 사람을 위한 정리는 애정이 있어야만 가능한 일인 걸 알기에 소중하게 읽었고, 팀 이야기가 나올 때마다 감동의 물결이 몰려왔습니다… 울고 있지는 않으니 안심하세요.
보노의 글은 읽는 사람을 생각하며 작성되었다는 걸 알기에 보노가 전하고자 했던 바를 모두 이해하고 싶어 한 자 한 자 열심히 읽게 되는 것 같습니다. 덕분에 반드시 거쳐야 했던 어려운 길을 보다 수월하게 지나갈 수 있게 되었어요. 개발에 대한 흥미를 이끌어 준, 좋은 글을 전해 준, 보노에게 감사합니다.
우리 팀에서 한 자리를 차지했던 사람으로써 이 글을 읽었을 때 너무 큰 공감 그리고 보노에게 너무 고맙다고 말하고 싶어서 댓글을 남깁니다.
우선 저는 UX에 치중된 사람이기에 역시나 개발에 대해 무지한 편이였고 이번 프로젝트를 참여할 때에도 코드를 짜는 부분에 욕심을 가지지 않았습니다. 물론 어려워서 제 스스로가 회피하게 된 것 같아요. 저는 제가 이해하지 못하면 극도의 스트레스를 받아 주저 앉아버리거든요. 그래서 이번에도 너무 무서웠고 우리 팀원들에게 개발을 이해하고 싶지만 그 이상은 하고 싶지 않다고 말하기도 했습니다.
그 다음날 보노는 저에게 그리고 우리 팀원들에게 설계에 대한 부분을 설명해주었어요. 물론 그 당시에는 100프로를 이해한 건 아니였지만 제가 가장 와닿았던 부분은 개발자, 기획자, 디자이너 모두 같은 선상에 있다는 말이였습니다. 여기와서 개발에 치중된 챌린지를 진행하다보니 디자인을 너무 개발을 하기 위한 작은 수단이라고 생각하는 이 현실이 좀 서운하기도 했거든요.(디자인에 시간을 할애하지 않으려고 하는 시간표들이 그렇게 느끼게 한 것 같아요.) 그런데 보노가 해준 이야기는 우리는 모두 같은 목표를 향해 나아가는 사람들이고 우리가 같은 것을 이해한다면 확실한 시너지를 낼 수 있겠다 그리고 저희 팀은 이걸 해냈다고 생각합니다. 보노가 그리고 우리 팀원들이 서로의 가치들을 존중하고 있다는 사실만으로도 제가 느꼈던 서운함이 다 해소되는 느낌이였어요! 그래서 너무 고맙다고 말하고 싶었습니다!!!
보노랑 같은 팀이라서 너무 행복했습니다@>@ 좋은 글 잘 읽고 갑니다
현재는 아니지만 과거 개발을 했을 때 많이 들었던 생각이라 공감이 가는 포스팅이였습니다.
비단 개발 뿐만 아니라 여러 직군에서도 참고 할 만한 글 같아요. 정말 잘 읽었습니다.