액티비티

[위코드 X 원티드] 프리온보딩 백엔드 - 여섯 번째 기업과제 후기

yjs3819 2021. 11. 23. 10:16
728x90

마지막 팀과제

이번 과제는 마지막 팀과제로 좋은 팀과 협업할 수 있는 마지막 기회였다.(이 프로그램 내에선 그렇다!)
이번 기업은 디어코퍼레이션으로 전동 킥보드관련 회사이다.

이번 과제는 어려운 점이 몇가지 있다.

  1. 변경에 유연한 설계
  2. 공간데이터타입

위 두가지 핵심 문제를 팀과 고민하여 해결하는 것이 중요하였다.

어떻게 해결하였는지, 그리고 또 팀과 협업할 때 어떤걸 느꼈는지 하나하나 써보겠습니다!!

문제에 대한 접근법

우리는 변경에 유연한 설계에 대한 해결을 어떻게 할지 고민하였다.

처음에 든 생각으론 기존에 아는 정보에서 확장하는 수밖에 없었다.

객체지향프로그래밍 OOP에 나는 전부터 관심이 있었고, 객체지향의 사실과 오해, 일명 토끼책이라고 불리는 책을 두번 정독한 경험이 있다.
그래서 나는 얼핏 어떤 설계가 유연한 설계인지, 어떻게 해야 객체지향적으로 설계할수 있는지 구체적으론 아니지만 대체적으로 알고 있었다.

항상 객체지향적으로 설계를 하려 노력하지만 잘안되더라..

그래서 나는 팀원에게 주도적으로 내가 아는 사실과, 책의 내용을 공유하며 '외부로 드러날 필요가 없는 객체의 상태(멤버변수)나 행동(메서드)가 드러나면 변경에 유연한 설계가 되지 못한다. 하나의 객체의 변경에 대한 파급이 외부까지 전달되어, 변경에 유연하지 않게 되버린다.'등의 얘기를 하였다.

실제로 변경에 유연한 설계가 되려면 변경의 파급효과가 적어야 하는데, 객체 내부에 숨길수 있는 부분을 외부로 드러나게 한다면 변경에 유연하지 않게 되버리고 우리의 문제해결에 실패할거라 생각한다.

그렇다면 변경에 유연한 설계, 객체지향적으로 설계하려면 어떻게 해야할지 내가 아는 선에서 팀원과 공유하며 고민하였다.

  1. 객체가 무엇, 무엇이 있을지 식별한다.
  2. 메시지가 어떤 것이 있을지 생각한다.
  3. 해당 메시지를 어떤 객체가 수신할 수 있는지 생각한다.
  4. 메시지를 수신할수 있는 객체는 책임을 다하는 중, 또 어떤 메시지가 필요할지 생각한다.
  5. 해당 메시지는 또 어떤 객체가 수신할 수 있는지 생각한다.
  6. ... 반복

위의 매커니즘을 통해 우리는 도메인 모델을 설계했다.

나는 대외할동 면접에서 이러한 질문을 받았다. '도메인 모델과, ERD를 둘다 만드셨던데 이유가 뭔가요?' 실제로 두개의 설계는 거의 차이가 없었고 모습이 유사했다. 나는 진짜 멍청하게 '내가 강의를 듣던 선생님이 그렇게 하셔서요..'라고 답변했다. 정말 '어떤 이유가 있어서'가 아닌 '남들이 하기에 단순히 따라한 것'이였다. 지금생각하면 정말 같이 일하고 싶지 않는 답변이라 생각한다.

왜 이러한 도메인 모델을 설계했을 까? 왜 저 과정을 반복하였을까?

변경에 유연한 설계

변경에 유연하다는 것은 요구사항이 변경되어, (소프트웨어에선 요구사항의 변경은 매우매우매우매우 잦다.) 코드가 수정되어야 할 때, 수정되어야하는 그외의 코드에는 변경의 파급효과가 적은 것이라 생각한다. 이는 구현과 외부 인터페이스가 완전히 분리되어 있어야 가능하다고 생각한다.
구현은 변경이 되어도 괜찮은 객체 내부이고, 외부 인터페이스는 변경이 되면 안되는 객체 외부이다.

즉, 구현이 변경된다면 객체 혼자 바뀐것이므로 변경의 파급효과가 객체 외부까지 흘러가지 않게되어 변경에 유연하다. (내부 외부의 완벽한 분리!!)

그렇게 하기 위해선 실제로 객체들이 협력을 할때 정말로 필요한 내용만 외부에 드러나야 한다 생각한다.

그래서 기능 구현을 위해 정말로 꼭 외부에 드러나야하는 메시지부터 생각하고 해당 메시지를 수신할 객체를 생각한 것이다.

객체부터 생각하게 된다면 불필요한 메시지가 생길 확률이 크고, 그만큼 외부에 공유되는 것이 많기에 변경할 때 파급효과가 크게 될것이며 변경에 유리하지도 유연하지도 않은 설계가 될것이다.

고맙게도 팀원은 나의 의견을 매우 잘 경청해 주었고 나도 팀원들의 얘기를 들으며 뭐가 나은지 고민을 하였다.


(팀원과 열심히 만든 도메인 모델)

위 도메인 모델을 토대로 코드 구현을 해나갔다.

역할에만 의존, 구현체에는 의존하지 않는다.

클라이언트 코드는 역할인 인터페이스만 의존하고 실제 인터페이스를 구현한 구현체에는 의존하지 않아야 한다.
왜 그럴까?

구현체가 바뀌어도 클라이언트 코드는 인터페이스에만 의존하고 있기 때문에 변경의 파급 효과가 적기 때문이다.

그렇기에
우리는 변경이 자주 일어나는 부분에 대해선 인터페이스인 역할을 먼저 정의하고, 해당 인터페이스를 구현하여 설계하였다.

새로운 규칙이 추가되거나 수정되면 해당 인터페이스를 구현하는 클래스만 하나 새로 만들기만 하여도 변경이 끝나기 때문에 매우 유리한 설계라 생각한다.

이러한 점에 대해서 내가 먼저 얘기를 꺼냈을 때 팀원은 모두 좋다고 하였다.
하지만 의문을 가진 팀원도 존재했는데 그때면 나도 한번더 고민하게 되는 좋은 시간이였다.

우리는 NestJS를 사용하였는데, 스프링은 구현체를 스프링 빈으로 등록하고, 해당 빈을 우선순위를 둬서 주입받을 수 있어, 완벽한 DIP를 이룰수 있지만 NestJS는 모듈에 코드를 수정해야 했다.

NestJS 프레임워크에 대해 조금더 알게된 좋은 시간이였다.

공간데이터 타입

재밌게 개발해던 도중, '공간 데이터 타입'이라는 난관을 만났다.

데이터베이스 필드중, 공간데이터 타입이라는 필드 타입이 존재하는 걸 이번에 팀원 모두 처음 알았고 처음 적용해 보았다.

막막했지만 서로 구글링한 결과를 통해 소통하며 해결하니 금방 문제를 해결했다.

한명 보단 두명 두명보단 팀!!
역시 팀과 함께하면 아무리 어렵더라도 어떠한 해결도 해결할 수 있을 거라 생각한다.

각자 서로 다른부분을 알고있다면 팀과 소통해 서로간의 지식에 부족한 점을 채워 궁극적인 문제를 해결할수 있다는걸 느꼈다.

잡초팀 짱!

마지막 팀과제

3주간 밤도 많이 새가며, 소통도 엄청 많이 해가며 팀과 과제를 해왔다.
처음으로 줌을 24시간동안 들어가 있으면 방이 닫힌다는 사실도 알게 되었다.
개발 자체에 대한 즐거움을 알게 된것도 중요하지만 팀원과 함께하는 즐거움을 알게 되었다는 것 또한 나에겐 중요한 경험이였다.
잡초팀 모두 열심히, 열정적으로 하였기에 팀을 서로 믿을 수 있었던 것같다.

728x90