회고

오늘 미션은 Git 명령의 동작 방식을 이해하고, 기본 명령 동작을 그대로 구현하는 VM Git을 만드는 것이었다.

  • File, Commit, Repository, Local, Remote 주요 기능을 담당하도록 module을 나누거나 class로 구분해서 작업한다.

    • 입/출력을 위한 모듈 외에 모든 기능은 바닐라 자바스크립트로 구현한다.
  • 가상으로 git 동작을 확인하는 프로그램을 작성한다.

  • vmgit을 시작하면 셀 프롬프트와 비슷하게 명령을 입력받는다.

요구사항은 위와 같았는데, 제대로 파악하지 못한 상태로 설계부터 시작하였다. 이러한 이유로, 가상으로 Git 아닌 실제 파일을 기준으로 1 시간동안 설계하였다...

설계

init 명령어

  • Repository를 생성한다.
  • 각 Repository는 _vmGit, _remote 디렉토리를 가지고 HEAD, status 파일을 가지고 있는다.
  • HEAD는 최신 커밋 파일(개체) 경로를 저장한다.
  • status는 Repository의 working area, staging area, git repository 정보를 저장한다.
    • 각 area는 파일의 경로를 가지고 있는다.

checkout

  • 현재 head 값을 HEAD 파일에 저장하고, 이동할 repository의 Head 파일을 읽어와 head에 저장한다.

add

  • 해당 파일에 대한 working area 정보를 staging area로 변경한다.

commit

  • 실제 Git처럼 BLOB 파일을 생성하지는 않지만 Commit 파일(개체)를 생성한다.
  • tree 디렉토리를 생성하고 staging area에 있는 파일을 모두 복사한다.
  • Commit 파일(개체)에는 commit message, tree 디렉토리(Tree 개체) 경로, 이전 Commit 파일(개체) 경로를 저장한다.

status

  • status에서 working area, staging area, git repository에 저장된 파일 경로를 기준으로 최근 수정된 날짜(stats) 정보를 노출한다.
  • ex) readme 2019-03-26 09:28:05

log

  • head가 가리키는 최신 커밋을 기준으로 이전 커밋을 탐색해가며 커밋 정보를 노출하였다.
  • 각 커밋은 링크드 리스트 방식으로 이전 커밋 정보를 저장한다.

push

  • local에서 가리키는 최신 commit을 기준으로 _remote 디렉토리의 HEAD가 가리키는 최신 커밋과 동일한 커밋을 만날때까지 탐색하며 _remote 디렉토리에 각 커밋을 복사한다.
  • _remote 디렉토리의 HEAD를 local에서 가리키는 최신 commit로 업데이트한다.

IMG_0160.JPG

개발이전에 충분한 설계과정을 가졌으나, 기능 중심의 설계를 하며 스파게티 코드를 작성하는 잘못된 결과를 나았다.

구체적인 원인을 따져보면, 기능 중심의 설계(add, commit, ...)하며 객체 지향적으로 설계하지 못하였다.

이번 미션은 스스로에게 "객체 지향적 설계를 잘하려면 어떻게 해야하는가?" 질문을 되뇌이게 하였다.
결론은 책임 주도 설계테스트 주도 설계이다.

책임 주도 설계

  1. 기능 중심적으로 생각하지 마라!

  2. 도메인에 필요한 최소 단위의 객체를 생각하라.

    • ex) Git -> File
    • 요구사항에 자주 언급되는 객체(요소)가 최소 단위 객체일 가능성이 있다.
  3. 각 객체의 책임을 생각해보자.

    • 각 객체가 필요한 메시지를 생각해본다.
    • 메시지를 수신할 객체를 생각해본다.
    • 메시지가 수신자(객체)의 책임을 결정한다.
  4. 객체 인터페이스 구성한다.

    • 객체들이 수신하는 메시지를 바탕으로 객체들의 인터페이스 구성한다.

다시 설계해보자

vmGit의 최소 단위 객체는 File 이다.

참고

  • 객체지향의 사실과 오해 / 조영호