/ios-number-baseball

iOS 커리어 스타터 캠프 숫자야구

Primary LanguageSwift

⚾️ 숫자야구 프로젝트

  • 팀 프로젝트(3인)
  • 프로젝트 기간: 2021.10.05 ~ 2021.10.08

목차


순서도

flowchart

구현사항

  • 함수만을 활용하여 숫자 게임의 기능을 구현
함수명 설명
createRandomNumbers 랜덤 숫자 생성하여 반환
classifyStrikeOrBall 정답과 비교하며 스트라이크/볼 카운트 판정
classifyStrikesumUpScoresOrBall 스트라이크/볼 카운트 합산하여 반환
sumUpScores 두 점수를 전달하여 게임의 결과를 반환
printVictoryMessage 승리 메세지를 출력하고 게임 카운트를 초기화
startGame 게임 시작

고민되었던 점 및 해결방안

1. 순서도 작성

  • 동료와의 커뮤니케이션을 위해서 순서도 작성 방법에 대해 익히고, 작성 기준에 대해 동료들과 같이 고민해보았다.

2. 커밋 컨벤션

  • 첫 협업 프로젝트인 만큼 커밋 컨벤션 및 스타일을 미리 정리하여 작성 기준을 같이 맞춰보았다.
  • 앞 기수 분들의 컨벤션들을 참고하여, 커밋 메세지 스타일 가이드 중 하나인 Karma Style을 따르기로 결정했다.

3. 변수 및 함수 네이밍

  • 함수 단위에 대해 고민해보았다. 한가지의 기능만 할 수 있도록 구상해보았고, 변수 또한 역할에 맞는 적절한 네이밍을 고민해보았다.
  • 네이밍은 Swift API Design Guidelines 부분에 Naming 파트를 참고하여 구상했다.

4. Array vs Set

  • 랜덤한 3개의 숫자를 구하기 위해서 어떤 자료형을 사용할지 고민해보았다. Int.random 메소드를 활용하여 랜덤한 정수를 뽑고, 중복되지 않는 3개의 숫자를 뽑아야 했는데, 반복문을 돌면서 어떤 자료형에 넣어주는 것이 더 효율적인지 고민해보았다.
  • 고민한 결과, Swift에는 shuffled라는 메소드가 존재했고, 이를 활용하여 1부터 9까지의 정수를 배열로 생성한 후 shuffled 메소드를 통해 배열을 섞고, 앞에 3개의 수만 반환하도록 구현하여 해결하였다.

5. 하드코딩 지양하기

  • 하드코딩을 지양하기 위해서 변수의 단위 또한 고민하였다. 변수가 체이닝으로 인해 길어지는 경우, 혹은 조건문이 길어져서 한눈에 알아보기 힘든 경우 이를 쪼개서 별도의 변수로 선언해주므로써 재사용성, 가독성 향상에 힘써보았다.
  • 함수 또한 하드코딩을 피하고, 재사용성을 높히기 위해 파라미터로 받을 수 있는 부분은 최대한 활용해보려고 하였다.

이외에도 여러가지 고민들을 하였다.

- 여러 함수에서 여러 번 사용되는 변수를 전역변수로 선언하는게 나을지 파라미터로 연달아서 전달하는게 나을지 고민
- 전역변수 선언 지양하기 위해 inout 키워드를 얼마나 사용할지 고민
- 한 개 이상의 값을 반환받을 때 배열을 사용할지 튜플을 사용할지 고민
- 하드코딩을 피하기 위해 변수를 따로 선언하는 방법
- 볼과 스트라이크 개수를 헤아리는 적절한 방법
- 올바른 범위의 값이 입력되었는지 검증하는 방법

코드리뷰를 통해 개선했던 것

  • 들여쓰기 제한 조건 충족 위해 함수 내의 기능을 함수로 분리
    • checkBallCount함수 내 if문 → classifyStrikeOrBall 함수로 분리
    • startGame 함수 내 if문을 printVictoryMessage 함수로 분리
  • 볼과 스트라이크 값을 반환할 때 배열 사용 → 튜플 사용
  • 가독성 향상, 휴먼에러 및 하드코딩 방지
    • 정수 0 → .zero 이용
    • 정수 9 → victoryGoal 변수 생성
  • 일일히 출력하던 부분을 reduce를 이용해 String으로 변환해 한 번에 출력하도록 수정
  • guard문을 사용해 숫자를 한 번에 맞추는 경우를 제한했으나 한 번에 맞추는 경우는 드물고, 해당 부분의 가독성이 떨어져 삭제
  • 함수 재사용성을 고려하여 3으로 지정했던 부분 수정
  • 역할에 맞게 변수명 및 함수명 수정
  • 값이 변경되지 않을 변수(var)를 상수(let)로 변경함

궁금했던 것

  • refactoring의 스킬, 그리고 이러한 방법들이 왜 좋은걸까?
* 하나의 함수에서 너무 많은 일을 하고 있지 않은지 확인한다.
* 새로운 타입을 만들어 활용한다.
* 구현체를 직접적으로 의존하지말고, 추상화한 상위 클래스 또는 프로토콜을 의존하도록 설계한다.
* 객체의 내부 프로퍼티를 보호하고, 인터페이스를 추상화한다.

내가 생각했을 때는 함수의 길이가 너무 길어지는 것도 안좋지만
그렇다고 조금 길어지는 정도 가지고 분리하면 안되는 부분을 따로 분리하여 
함수를 만들어도 가독성이 떨어지는 것 같다. 
로직을 변경해보는 다른 방법도 한번 고려해보는 것이 좋을 것 같다는 생각이 들었다. 
항상 어려운 상황이 닥치게 되면 피하려고만 했는데 그러지말고
일단 발생한 문제에 맞서서 다르게 고민해봐야겠다.
  • 전역변수를 지양하는 이유는 무엇일까?
- 전역변수를 사용하면 생기는 문제
    * 어디서 값이 변경되는지 추적이 어렵다.
    * 프로그램 내 변수와 함수 등 여러 요소들과 간섭이 심해짐
    * 전역 변수는 모든 곳에서 보이므로 네임스페임스가 오염된다.
    * 전역 변수가 메모리 할당 외에 side effect가 있으면 문제 발생 소지가 크다. (상호 의존 등...)
    * 전역 변수는 생명 주기가 길다. 따라서 메모리 리소스도 오랜 기간 소비한다.(메모리릭)
  • 프로젝트 제약사항의 들여쓰기 기준
- 프로젝트 요구사항에 대해서 "이 부분은 고려해야하는 것이 아닌가?"하는 생각이 들 때면 
요구사항을 제시한 사람에게 찾아가 물어보는 것이 가장 정확한 답이 될 수 있겠다.