[Vanilla JS] 자판기 - 페어프로그래밍 프로젝트

Kyle·2021년 3월 28일
1

project

목록 보기
7/13
post-thumbnail

자판기

깃허브 링크

개발 기간: 03/22 ~ 03/26

구현한 기능

  • 실제 자판기와 동일한 기능 구현
  • 상품화면, 자판기모니터 화면, 지갑화면이 동일한 상태를 공유해야 되기 때문에 옵저버 패턴을 적용

실행화면

기본 동작
비동기 동작

구현과정

이번 미션은 하나의 상태의 변화에 따라서 각자 다른 View들이 그 상태를 어떻게 공유해야 할까 라는 것에 집중한 미션이었다.

처음에 옵저버패턴을 적용했던 방식과 그때 발생한 문제점, 그리고 어떻게 변경해서 해결했는지를 작성해 볼 예정이다.

수정 전 구조

변경 전 다이어그램

지갑 돈 클릭, 반환 버튼 클릭, 상품 클릭이 발생하면 View의 event handler에서 model.notify()를 해주었다.

각 Model의 Observers

  • Wallet Model의 Observers
  1. Wallet View - wallet model 데이터 변경(돈--) & wallet 렌더링
  2. Process View - vending money(돈++) & 로그 출력 & process screen 렌더링
  3. Product View - product 렌더링
  • Process Model의 Observers
  1. Wallet View - wallet model 데이터 변경(돈++) & wallet 렌더링
  2. Process View - vending money(돈--) & 로그 출력 & process screen 렌더링
  3. Product View - product 렌더링
  • Product Model의 Observers
  1. Process View - vending money(돈--) & 로그 출력 & process screen 렌더링
  2. Product View - 재고 업데이트 && product 렌더링

문제점

View와 Model의 의존성

옵저버 패턴을 단지 모델에 각 View에 메소드들을 넣어놓는 저장소 같은 역할로만 생각했습니다.

그래서 click이벤트가 일어날 때 이벤트핸들링 해주는 View에서 model.notify()해주었습니다.

이렇게 되면 구독자들(View)에게 알려주는(notify)해주는 역할을 Model이 아닌 View에서 하게되는 이상한 구조가 됩니다. 또한 Model의 역할을 View에서 해주고 있다보니 Model에 대한 의존성도 높아질 수 밖에 없었습니다.

subscribe해주는 순서를 신경써줘야한다.

모델의 상태 변경을 옵저버가 실행시켜주다보니 실행 순서에 민감해지는 구조가 됐습니다.

오류 예시)

  • 현재 Wallet Model의 Observers의 등록된 순서: Wallet View -> Process View -> Product View

    Wallet View에서 클릭한 금액에 따라 Process View에서 모델의 금액을 업데이트해준다. 업데이트된 모델의 금액을 기반으로 Product View에서 구매가능 상품을 표시해준다.

  • 순서가 다를 경우 : Wallet View -> Product View -> Process View

    Wallet View에서 금액을 클릭 했지만 Process View가 모델의 금액을 업데이트하기 전에 Product View가 렌더링을 해버리게 된다. 클릭 이전의 가격을 기반으로 상품을 렌더링 해버려 구매가능 상품 표시에 오류가 생긴다.

수정 후 구조

변경 후 다이어그램

클릭이벤트가 일어날 때 각 모델의 상태를 변경 시켜줍니다. 각 모델에서 상태가 변경 될 때 model.notify() 해주게 리팩토링했습니다.

각 모델에서 상태가 변경 될 때 model.notify() 해주게 리팩토링했습니다.

수정 전에는 notify()시, 모델 상태의 업데이트와 그 값을 활용해 렌더링을 하는 함수를 실행했다면, 리팩토링 후에는 모델 상태의 업데이트와 렌더링을 분리시켜 순서의 의존도를 없앴습니다.

모델과 뷰 역할 분리

모델과 뷰의 역할 분리를 했습니다. Model은 상태값 관리에 집중하고, View는 렌더링과 이벤트 핸들링를 하도록 리팩도링했습니다.

Log Model, Log View 생성

Process Model에서 관리하던 Vending Machine Money와 Log 2가지 상태를 관리하던 것을 Log Model과 Log View를 만들어서 하나의 상태만 관리하도록 리팩토링했습니다.

각 Model의 Observers

  • Wallet Model의 Observers

    금액이 변경했을 때 => Wallet 렌더링

  • Log Model의 Observers

    Log 데이터가 변경 됐을 때 (push) => Log 렌더링

  • Process Model의 Observers

    Vending Machine Money가 변경됐을 때 => Process, Product 렌더링

  • Product Model의 Observers

    재고가 0인 item이 있을 때 => Product 렌더링

회고

코드스쿼드에서 처음으로 한 페어프로그래밍이었다. 페어프로그래밍을 하기 전 걱정이 많았다. 의견은 잘 조율될 수 있을까? 같이하면 어떻게 잘 할 수 있을까? 이런 고민들을 했던 것이 무색할 만큼 많은 것을 배우고 좋았던 일주일이 아닌가라는 생각이 든다.

일단 2명이서 하나의 프로젝트를 하는 것이기 때문에 2명이 프로젝트를 바라보는 생각을 일치시켜야 됐다. 이 과정에서 자연스럽게 설계를 전보다 확실하게 하게 되고 이번 미션 중 포인트였던 옵저버 패턴에 대해서 제대로 학습할 수 있게 이어진 것 같다. 이렇게 구체화를 해놓고 작업을 하면서 장점이 리팩토링에서도 드러났다. 우리는 리뷰는 받을 때마다 크게 구조를 뒤엎었는데 이때 대규모 수정 작업임에도 불구하고 기존 설계한 부분에서 변경이 일어나는 것이기 때문에 수월하게 진행할 수 있었던 것 같다.

또 평소에 코딩을 할 때 집중력이 많이 부족하다고 생각했다. 기능 단위로 하나를 구현하고 나면 집중력이 급격히 떨어졌다. 하지만 페어프로그래밍을 하면서는 얘기를 하거나 서로 상황을 맞춰가면서 진행해서 그런지 집중하는 시간이 훨씬 많아졌다. 그만큼 힘들기도 했다.

일주일 동안 함께 리팩토링 과정을 하면서 많이 배웠다. 혼자 할 때는 리뷰에 나오면 적당히 그렇구나 하고 수정하는데 함께 작업을 하고 리팩토링 방향을 함께 논의하뒤 결정해야 되기 때문에 말이든 글이든 리팩토링하는 근거들을 표현하다 보니까 왜 해야 되는지에 대해 구체적으로 생각해볼 수 있는 시간을 가졌다. 5일 동안 주나미하고 페어프로그래밍을 하면서 서로의 코딩 스타일을 보면서 많이 배우고 재밌는 한 주를 보냈다.

profile
Kyle 발전기

0개의 댓글