하는대로 되게하는 개발자

8 분 소요

해당 포스팅은 개발자 세미나 발표를 위해 작성되었습니다.
포스팅에서 사용하는 어휘나 문구가 부적절할 수 있습니다. 🙇‍♂️

login();

하는대로 되게하는 개발자

안녕하세요.

되는대로 하는 개발자 Log입니다.


여러분 어떤일을 되는대로 하는 것하는대로 되게하는 건 어떤 차이가 있을까요?


저는 이 둘 사이의 근본적인 차이‘어떤 일을 세부 단계로 나누는 것‘과

‘각 단계에 대해 뚜렷한 목표를 설정하는 것’이라 생각합니다.


오늘은 되는대로 하는 제가 최근 프로젝트들을 수행하며,

하는대로 되게하기 위해 고민하고 실험해본 경험들을 공유해보려 합니다.



어찌저찌 끝나는 프로젝트들

지금까지 저는 프로젝트들을 수행하며, 초기 목표대로 프로젝트를 완수한 경험이 전무합니다.

초기 개발 범위 개발 실패, 일정 완수 실패, …


프로젝트는 대게 어떤 개발 범위에 대해 언제까지 완료되는지,

해당 구현물의 구현도가 어느 정도 되는지에 따라 평가되고 분류 됩니다.


지난 프로젝트들에서는 매번 개발 범위를 축소해서 일정내에 완수하거나,

정해진 개발 범위에 대한 마감 일정을 지키지 못해 마감 일정이 늘어나거나,

하는 식으로 프로젝트들이 어찌저찌 끝났었습니다.


휴…


성공하는 프로젝트

image

이를 성공한 프로젝트, 실패한 프로젝트로 분류 한다면, 실패한 프로젝트로 분류됩니다.

마감 일정에 대한 실패, 개발 범위에 대한 실패, 구현도 저조로 인한 실패


성공한 프로젝트, 개발 범위에 대한 구현도를 최대로 마감 일정내에 모두 완수한 프로젝트가 되려면,

어떻게 해야 할까요?


초기 분석의 중요성

프로젝트는 참여 인력이 수행해야 할 일의 개발 범위와 일정을 고려할 때, 때때로 불가능에 가까울 수 있습니다.

리소스를 고려하지않고 무리한 일정을 강제하는 것과, 충분한 리소스로 여유로운 일정으로 진행하는 것

두 방식 모두 잘못된 프로젝트 일정 관리 방식이라 생각합니다.

일단 갈아넣고 보는 방식, 한가로이 허송 세월하는 방식 모두 잘못


그렇게 되면 결국 실패한 프로젝트로 나아가게 됩니다.


그렇다면 이런 상황을 어떻게 알아차리고, 성공한 프로젝트가 되도록 바꿀 수 있을까요?


이를 알아내는 가장 좋은 방법프로젝트 초기에 분석과 설계 단계에서 정확한 예측을 하는 것입니다.

프로젝트 초기 분석이 실패한다면, 일정을 제대로 산출하는 것은 거의 불가능합니다.

이를 방지하기 위해서는 초기 분석과 설계 단계에서 명확하고 정확한 예측을 산출하려는 접근이 필요합니다.

이것이 바로 ‘하는대로 되게하기’ 위한 핵심 전략입니다.


엑셀부터 켜는 개발자

TigerDragon : Log야 잘하는 개발자는 어떤 개발자인지 아니?
Log : 어,,, 코드 잘쓰는 개발자요?
TigerDragon : 아니야, 엑셀부터 켜는 개발자가 잘하는 개발자야.

엑셀부터 켜는 개발자,

몇 년전 이전 회사 차장님께 들었던 아직도 인상 깊은 문장입니다.


코드를 작성하기 이전에 설계부터 하는 개발자가 잘하는 개발자다.

라는 의미로 저한테 말씀해주셨던 얘기인데,

그 당시에는 그냥 오 뭔가 멋있는 말이다. 정도로 받아들였지만

요즘들어 점차 더 의미를 알아가고 있는 문장입니다.


Miro부터 켜는 개발자


Miro 는 처음 DDD를 접하고, DDD에서 자주 등장하는 Event Storming 이라는 분석 단계를 시도해보기 위해

여러 분석 도구를 찾다가 선택한 사이트입니다.

지원 기능들이 협업 수정에 직관적이여서 요즘 프로젝트 설계, 분석 단계에서 사용하고 있는 분석 툴 사이트입니다.

최근 진행했던 프로젝트에서 해당 분석 툴로 프로젝트 설계, 분석을 진행했던 방법을 공유드리려 합니다.



Event Storming

분석, 설계 단계를 중요시 해본 최초 프로젝트는 상품권 프로젝트로,

회원이 같은 회원에게 서비스 상품권을 선물하고, 선물받고,

이를 관리자가 관리할 수 있는 기존 서비스에 추가 기능을 구현하는 프로젝트였습니다.


해당 프로젝트 당시에 DDD라는 개발 기법을 접하고,

이를 시도해보기 위해 분석 단계에 Event Storming 이라 불리는 단계를 거쳐보고 싶었습니다.

Event Storming
도메인 주도 설계(DDD)를 위한 강력한 작업 세션 방법론,
공동체의 모든 이해 관계자가 한 방에 모여서 비즈니스의 주요 이벤트를 매핑하고,
비즈니스 프로세스를 이해하고, 모델을 설계하는 것을 목표로 함


DDD 설계론에 대한 얘기가 핵심 주제가 아니라,

해당 설계 단계때 진행했던 방법과 얻었던 점들을 말씀드리려 합니다.

도메인 이벤트의 시각화

해당 프로젝트 때 시도해본 분석 단계의 핵심

도메인 이벤트, 비즈니스 로직의 시각화 였습니다.


도메인 이벤트, 비즈니스 로직의 흐름을 정의하기 위해,

최초에 특정 주체별로 발생 가능한 이벤트들을 단순하게 정의했습니다.


그 후 이를 조금 더 세분화하여 발생 가능한 로직의 흐름을 명세하고,

포스트잇 색깔별로 작성 내용을 구분지어 시각화에 중점을 두었습니다.

로직 시각화의 장점

결국 구현하려는 로직을 시각화하는데에 중점을 둔 분석 방식이었습니다.

산출물을 담당 기획자, 개발 팀장님과 회의 때 사용했습니다.

말로 로직이 나열된 PRD와 화면 설계서를 분석하고,

이를 시각화하여, 기획자가 설계한 비즈니스를 실제 구현하는 개발자가 함께 토의하며 공동의 이해를 구축하는 것

기획 의도를 파악하는데 용이했고,

이 과정에서 설계 의도를 잘못 이해한 부분과 설계 미스 부분들을 찾기 수월했습니다.


진행하던 상품권 프로젝트는 가성비 이슈로 수행 과정에 중단되고,

다음 프로젝트를 진행하게 되어 이 외에 큰 이점을 얻을 순 없었습니다.

API 하나 개발하고 끝난 프로젝트..


Domain Modeling

다음 진행 프로젝트는 차량관제시스템 FMS(Fleet Management System) 프로젝트로,

기존 렌터카 회사 차량에 장착된 관제 모듈을 통해,

차량을 관제하고 관리하는 신규 시스템 구축 프로젝트 였습니다.


해당 프로젝트는 초기 구축 프로젝트였다보니, 설계해야 하는 모델량도 많고,

관리 시스템이다 보니 각 모델 간의 연관도도 높았던 프로젝트 였습니다.

이번 프로젝트 설계 분석에서 집중했던 부분은 Domain Model 그 자체였습니다.


도메인 모델의 시각화


자, 여러분 게시판 댓글 기능을 개발해야 합니다.


라는 문장을 들으면 백엔드 개발자는 사용자, 게시글, 댓글 테이블을 생각하고,

그래서 대댓글 있음 없음?

프론트 엔드 개발자는 댓글 작성 화면을 생각한다고 합니다.

진짜로 이렇게 생각하는지는 모름 ㅋㅋ


여기서 얘기하고 싶은 부분개발자는 개발할 때 자신만의 머리속 추상적인 이미지를 토대로,

개발 설계를 진행한다는 점입니다.


이번 프로젝트는 제공하는 총 기능을 각 단계 개발 차수로 세분화하여,

점차 기능을 제공하는 형태로 진행되었는데요.


백엔드 입장에서는 각 단계를 진행하는데에 필요한 최소 모델 설계와,

향후 기능을 생각한 확장성 있는 모델 설계가 중요했던 프로젝트였습니다.

[EX] 처음 로그인 기능 개발하는데 차량, 소모품 모델은 필요 없다,
순차적으로 최소 어떤 모델들이 추가되어야 하는가?
추후 개발 차수 기능으로 인해 모델 구조가 변경되는가?


이를 위해 이번 프로젝트에서는 프로젝트 기간 내내 모니터 한칸에 아래와 같은 설계 모델을 띄어놓고,

매번 이 모델을 보고 수정하는 일을 반복하였습니다.


모델 시각화의 장점

단순히 테이블을 설계하는 것이 아닌, 실제 개발할 때 사용하는 Model, Entity, VO를 시각화 하는데 중점을 두었습니다.

해당 시각화각 모델간의 연관성, 결합성 등이 가시적으로 눈에 들어왔고,

설계된 기능을 구현하기 위해 각 차수 별로 모델들을 조금씩 수정하고 다듬어 가며,

설계 미스들을 찾거나, 위기감 있는 모델들을 분리, 분화 시키는데에 효과가 있었습니다.


더욱 좋았던 점은, 해당 모델이 익숙해 짐에 따라,

기획 변경이나 신규 기능 대응에 있어서 조금 더 명확하게 개발자간에 이야기 나눌 수 있었다는 점이었습니다.


또한 신규로 투입하는 인력에게 기존 개발 코드와, 분석 내용을 공유하는데에도

해당 산출물을 사용할 수 있었습니다.

설계 모델에 매핑하며 개발 로직 분석


정말 장점밖에 없는것 같은 이 분석 산출물들반드시 장점만 존재하진 않았습니다.

아래와 같은 이슈들을 맞이합니다.


산출물과 구현 코드의 이원화

문서는 유효한 상태를 유지하고, 프로젝트 활동과 관련을 맺으며, 최신 내용을 담고 있어야 한다.
Domain Driven Design - Tackling Complexity in the Heart of Software By. Eric Evans


앞서 살펴본 산출물들에서는 각각 비즈니스 로직, 모델의 시각화에 집중하여 작성하였습니다.

결국 구현하려는 코드를 시각화 한다는데에 의의를 가지고 있었습니다.


하지만 실제 프로젝트를 진행하면서 구현 코드를 작성, 혹은 작성된 코드를 변경하는 작업을 하게될 때 마다

설계 산출물과 구현 코드는 조금씩 이원화가 진행되었습니다.

설계내용과 상이하게 개발하거나, 설계된 개발 내용을 수정할 때 산출물은 수정하지 않는 일이 빈번히 발생


이는 결국 아래와 같은 이유로 산출물을 신뢰할 수 없게 만들었습니다.

  1. 설계 된대로 개발하지 않으니 산출물 신뢰도 하락
  2. 설계 내용이 개발 수정에 따라 이원화되어 있을 수 있어 산출물 신뢰도 하락

설계 산출물에 부족한 부분이 있거나, 급한 일정이나 중요도 있는 수정사항을 신속하게 대응하게 될 때, 혹은 문서 업데이트를 까먹었을 때

이러한 일이 발생했습니다.


이러한 일들을 해소시키려면 어떻게 해야 할까요?

제가 생각한 방법들은 이러합니다.


설계를 위한 설계

앞서 설계 산출물과 실제 구현내용이 구현 단계에서부터 달라지게 되는 경우는 대부분,

설계 내용실제 구현해야 하는 내용과 중요 부분이 상이하거나, 누락될 경우 발생했습니다.

  • 설계 내용

  • 실제 코드

    public JoinCompanyResponse execute(JoinCompanyRequest request) {
      // 요청값으로 생성 시도 회사 Entity를 생성
      Company companyByRequest = JoinCompanyMapper.toCompanyDomainEntity(request);
        
      // 사업자 등록번호 중복 여부 확인
      List<CompanyAggregate> companyAggregatesSearchDuplicateBusinessRegistrationNumber = companyPerpetuity.readCompany(
      CompanyAggregate.initForSearch(Company.builder().businessRegistrationNumber(companyByRequest.getBusinessRegistrationNumber()).build()), PageRequest.of(0, 1));
      validateExistBusinessRegistrationNumber(companyAggregatesSearchDuplicateBusinessRegistrationNumber);
        
      // 시스템 회사 설정 값 로딩
      List<CompanyAggregate> systemCompanyAggregatesWithControlSetting = companyPerpetuity.readCompanyWithControlSetting(
      CompanyAggregate.initForSearch(Company.initSystemDefaultCompany()), PageRequest.of(0, 1));
      validateSystemCompanyExist(systemCompanyAggregatesWithControlSetting);
      ...
        
      // 시스템 회사 설정 값 세팅
      companyByRequest.setCompanyControlSetting(makeCompanyControlSettingUsingSystemDefault(systemCompany));
      CompanyAggregate companyAggregate = CompanyAggregate.initForCreateCompany(companyByRequest);
        
      // 요청 회사 비승인 상태 생성
      CompanyAggregate insertedCompanyAggregate = companyPerpetuity.saveCompany(companyAggregate);
      Crew crewByRequest = JoinCompanyMapper.toCrewDomainEntity(request);
        
      // 요청 직원 정보 중복 체크
      List<CrewAggregate> crewAggregatesSearchDuplicateEmail = crewPerpetuity.readCrew(CrewAggregate.initForSearch(Crew.builder()
      .email(crewByRequest.getEmail()).build()),PageRequest.of(0, 1));
      validateNonExistCrewEmail(crewAggregatesSearchDuplicateEmail);
        
      // 요청 직원 저장
      CrewAggregate crewAggregate = CrewAggregate.initForJoinMasterCrew(crewByRequest, insertedCompanyAggregate.getRootId());
      crewPerpetuity.saveCrew(crewAggregate);
        
      ...
        
      // 정상 생성 응답 반환
      return JoinCompanyMapper.toResponse(insertedCompanyAggregate.getRoot());
      } 
    

실제 구현해야하는 내용에 비해 설계 내용이 너무 빈약


이를 되짚어 보니, 실제 구현 코드를 생각하면서 작성하는 것이 아닌,

산출물 단계를 완료짓기 위한 작업으로 인해 발생한 문제였습니다.

아 설계 과정도 겁나 많은데 언제 다해,, 빨리 코드 써야 하는데,,, 촉박한데 일정,,,


설계 과정이 너무 많아지고, 시간이 소요될 수 록,

분석 산출물은 결국 산출물 생산을 위한 산출물일 뿐

분석 산출물을 토대로 소스코드를 구현할 것이다 라는 가장 큰 목적과 멀어져 갔습니다.


참여 인원의 산출물에 대한 중요도

설계물과 실제 코드와의 이원화는,

개발 구성원들이 해당 산출물을 얼마나 중요하게 생각하는지의 차이에서도 발생했습니다.


산출물을 개발 주기 끝까지 가져가며 최신화할 중요 문서로 인지하는 인원은 문서 일원화에 집중했고,

단순 코드 작성 전을 위한 단계로 받아들이는 인원은,

문서 최신화 과정이 개발 주기의 병목으로 인지되어 문서가 이원화 되게 되었습니다.

코드 쓰기도 바쁜데 언제 고침? 에잇 쯧


그럼에도 불구하고

아무리 구현 코드를 상상하며 설계를 작성하더라도,

반드시 실제 구현 내용에 누락되는 일은 발생했고,


산출물 최신화의 중요도를 아무리 인지한 인원이더라도,

그냥 까먹어 버리면 답도 없었습니다.

ㅋㅋ 까먹을 수도 있지 ㅇㅈ


얼마까지 알아보셨어요?

결국 제가 생각한 해소 가능한 문제들코드 구현을 고려하지 않은 산출물, 너무 많은 설계 단계, 설계 중요도 인지의 상이 였습니다.

그냥 까먹음 등은 뭐 어떻게 할수가 없음 ㅇㅇ..

그리고 이를 해소하기 위한 노력은 결국, 설계 단계에 참여하는 구성원들이 정하는 몫이었습니다.


설계 단계에 참여하는 인원들끼리 토의를 나누며,

자신들이 작성할 코드 구현에 필요한 산출물에는 어떤게 필요 할지,

우리가 코드를 어떻게 구현할 것이니 이러한 산출물을 만들어보자.

설계를 위한 설계 단계, 굳이 작업할 필요 없는 설계 산출물은 어떤게 있을지, 더 축소 시킬 순 없는지,

이 설계 단계는 결국 안쓰이고 중요도도 낮고 시간만 오래 걸리는걸로 보인다, 그냥 빼자.

해당 설계 산출물을 어떻게 활용하고, 어떻게 관리할 것인지,

이 설계 내용으로 모델을 만들자, 그리고 코드 작성 단계 때는 이 단계 띄어놓고 생성하면서 계속 최신화하자

끊임없이 고민하는 것 밖에는 없었습니다.


100% 소스 구현도와 일치하는 산출물을 만드는데, 개발 일정을 100% 쓴다면 아무 의미 없는 작업이 될 것입니다. 거의 설명서 처럼 그대로 소스만 쓰면 되는 산출물이지만, 이거 만드는데 일정을 다쓴다면 무슨 소용?


우리가 성공하는 프로젝트, 하는대로 되게하기 위한 사전작업에 얼마까지 쓸 것인가?

매 프로젝트마다 다를것이고, 사람마다 다른 가치일 것입니다.

하지만 항상 저울질 해야합니다.


마치며

해당 포스팅에서는 하는대로 되게하기 위해, 성공적인 프로젝트 수행을 위한

설계 단계의 중요성에 대한 이야기를 해보았습니다.

그래서 결국 분석, 설계 단계를 철저히 하면 하는대로 되는것인가?

프로젝트를 성공적으로 수행할 수 있게 되는 것인가?

라고 묻는다면,

저도 아직 모릅니다.

ㅋㅋ ㅈㅅ


그저 프로젝트 이슈를 조기에 발견하고, 구성원들의 추상적인 생각들을 시각화해서 같이 초기에 이야기 나누는 것,

그걸 프로젝트 생명 주기 마지막까지 이어나가는 것,


이것이 프로젝트를 성공으로 이끌 것이다.

하는대로 되게하는 전략일 것이다.

라고 믿고 한번 해보고 있을 뿐입니다.


해보지 않고는 모르는 것들이 태반이니까요.

더 해보고 다시 뭔가 괜찮은게 나오면 또 말씀드리겠습니다.

오늘은 여기까지입니다.

안녕히가세요.

logout();


댓글남기기