Page tree
Skip to end of metadata
Go to start of metadata

스터디 회고

  • 오늘 스터디에서 진행할 부분을 논의해서 to do list를 작성한 후에 진행했다.
    • 최초 작성한 to do list를 계속해서 발전시키면서 진행하니까 현재 무엇을 하는 것인지에 대해 명확해서 좋았다. 
  • GridTest에서 Acceptance Test 개념으로 접근함. Acceptance Test를 가정하고 구현한 것은 아니지만 추후 확인해 보니 자연스럽게 Acceptance Test가 되었다.
  • Acceptance Test이다 보니 구현할 때 pseudo 코드 형태로 전체적인 흐름을 파악할 수 있는 코드 구현을 먼저 진행함. 컴파일 에러가 발생하는 상태에서 전체적인 흐름 파악에 우선함.
  • 전체적인 흐름 파악을 한 후 컴파일 에러가 발생하는 부분을 단계적으로 구현해 나가기 시작함.
    • rubymine의 경우 컴파일 에러가 발생하는 부분이 명확하게 인지할 수 있도록 해주지 않아 컴파일 에러를 빨리 해결하는 것보다 전체적인 흐름을 파악하는데 집중하도록 유도하는 것도 있었음.
    • eclipse의 경우 컴파일 에러가 명확하게 표시하다보니 먼저 컴파일 에러를 해결하려는 욕구가 생김. 자꾸 눈에 거슬리는 상황
  • 각 단계별 구현에서 단위 테스트 만들고 구현 완료하는 방식으로 접근한다.
    • 스터디에서 이 단계를 건너 뛰고 구현에 집중하다보니 같이 하는 친구 중의 한명이 단위 테스트가 필요하지 않겠다는 생각을 했다.
    • 구현을 완료하는 것보다는 좀 더 step by step으로 구현하는 것에 집중할 필요가 있겠다.
  • 각 단계별 리팩토링
    • 지금까지 실패하는 단위 테스트를 만들고 pass하는데 많이 집중했다.
    • 의식적으로 중간 단계에서 리팩토링하는 연습을 했다. 테스트 중간 중간에 리팩토링하는 과정을 거치는 것이 정말 중요하다.
    • 아무리 작은 변화라도 리팩토링할 부분을 찾는 연습을 하는 것이 무엇보다 중요하다는 생각이 든다.
    • 너무 많은 기능을 구현한 후에 리팩토링하는 과정은 너무 힘들다. 따라서 잘 안하게 된다. 코드 복잡도는 증가하고 개발 흐름이 명확하지 않게 된다.

개발 및 리팩토링하면서 배운 점

  • 지뢰 찾기 게임에서 아래와 같이 이웃 square를 구하는 메서드 구현 완료된 상태임
  def near_squares(x, y)
    arr = Array.new

    (x-1..x+1).each do |row|
      (y-1..y+1).each do |col|
        arr << get_square(row, col) unless out_of_index?(row, col)
      end
    end

    return arr
  end
  • square의 주변 마인 갯수가 0인 경우 자동으로 open하는 기능 구현 중. 이 기능을 구현할 때 앞에서 구현한 near_squares를 사용할 수 있겠다는 생각이 듦.
  • 하지만 약간의 차이가 발생함. near_squares 사용하는 것을 포기하고 중복이 생기더라도 이중 for문으로 일단 개발 시작함. 다음과 같이 구현 완료함.
  def open (x, y)
    raise IndexOutOfBoundError.new if out_of_index?(x, y)
    raise GameOverError.new if get_square(x, y).mined

    return if get_square(x, y).opened
    get_square(x, y).open
    return unless get_square(x, y).zero_near_mine_num

    (x-1..x+1).each do |row|
      (y-1..y+1).each do |col|
        open(row, col) unless out_of_index?(row, col)
      end
    end
  end
  • 일단 위와 같이 테스트를 pass하기 위해 무작정 달려가기 시작함.
  • 테스트를 pass한 후 위 두 소스 코드의 중복을 제거하기 위한 리팩토링을 시작함. 위 소스 코드를 보는 순간 이중 for문이 중복이고, 그 내부만 변경된다. code block(메소드)을 넘기는 방식으로 중복을 제거할 수 있겠다는 생각이 듦
  • 다음과 같이 중복 제거함.
  def open (x, y)
    raise IndexOutOfBoundError.new if out_of_index?(x, y)
    raise GameOverError.new if get_square(x, y).mined
    return if get_square(x, y).opened
    get_square(x, y).open
    return unless get_square(x, y).zero_near_mine_num

    near_squares_each(x, y) do |row, col|
      open(row, col) unless out_of_index?(row, col)
    end
  end

  def near_squares(x, y)
    arr = Array.new

    near_squares_each(x, y) do |row, col|
      arr << get_square(row, col) unless out_of_index?(row, col)
    end

    return arr
  end

  def near_squares_each(x, y)
    (x-1..x+1).each do |row|
      (y-1..y+1).each do |col|
        yield row, col
      end
    end
  end
  • 위와 같이 중복 제거함.

구현하면서 느끼고, 배운 점

  • 구현과 리팩토링을 분리해서 생각하는 것이 훨씬 더 명확하고 효율적이었다. 한번에 하나에 집중하는 연습이 된다.
  • 리팩토링하는 시점에 리팩토링만 집중하다보니 나은 해결책을 찾는 것에 명확해짐. 즉, 일단 구현해서 마음의 평정심을 가진 후 여유를 가지고 리팩토링을 하니 사고가 훨씬 더 열리게 되는 느낌이 들었다.
  • 위 코드를 리팩토링하면서 수업 시간에 배웠던 code block의 개념을 구체적으로 이해하는 것을 느꼈으며, 자바스크립트에서 배웠던 closure 개념을 위 예를 통해 학생들이 명확하게 이해하는 느낌이 들었다.
  • 여러 명이 같이 개발하다보니 이름을 정하는 것에 있어 좋은 이름을 찾을 수 있었다.
  • 활발한 논의를 하면서 구현하다보니 집중에서 구현하는 것을 경험했다.
  • No labels