Mar 04, 2021, TIL (Today I Learned) - 개발자의 효율적인 문서 작성법

Inwoo Hwang·2021년 8월 26일
0
post-thumbnail

학습내용


Optional Chaining을 활용한 값 접근

Optional Chaining이란?

참고하면 좋을 블로그👇👇👇

[옵셔널 체이닝 | yagom’s Swift Basic

[옵셔널체이닝(Optional Chaining) 알아보기 (feat. Flow chart) – Neph – Swift Knowledge and Projects (neph3779.github.io)](https://neph3779.github.io/swift/옵셔널체이닝(Optional-Chaining)/)

func getUserInput() throws -> Int {
        guard let unsafeUserInput = readLine() else {
            throw GameError.invalidInput
        }
        
        guard let integerUserInput = Int(unsafeUserInput) else {
            throw GameError.invalidInput
        }

기존에는 유저 입력값을 Optional StringInt바꿔주기 위해 guard let 구문을 두 번 사용 하였다.

그런데 이렇게 작성할 경우 불필요하게 코드가 길어진다는 느낌을 받았다. @Cory 가 주신 Optional Chaining을 활용 해 보라는 피드백을 따라서 아래와 같이 수정 하였다.

func checkUserInput() throws -> Hand {
        guard let stringUserInput = rawUserInput,
              let integerUserInput = Int(stringUserInput),
              let userInput = Hand(rawValue: integerUserInput)
        else {
            throw GameError.invalidInput
        }
        return userInput
    }

guard let..., let..., let... 값을 나열하고 한 번에 추출하니까 코드가 훨신 깔끔해 졌다.👍



EnumRaw value 접근

Enum이란?

참고하면 좋을 블로그 👇👇👇

Swift enum에 대해 알아보자! (기본편) – Neph – Swift Knowledge and Projects (neph3779.github.io)

class RockPaperScissors {
    var handOfComputer: Hand = .rock
    var handOfUser: Hand = .rock
    var rawUserInput: String? = ""
  
    enum Hand: Int {
        case rock = 1
        case scissor = 2
        case paper = 3
    }
.
.
.
.
.
.
.
.
.
.
  func startGame() {
          outer: while true {
              renewComputerHand()
              showMenu()

              rawUserInput = readLine()
              if let rawUserInput = rawUserInput {
                  if rawUserInput == "0" {
                      break outer
                  }
              }

              do {
                  if let safeHandOfUser = RockPaperScissors.Hand(rawValue: try checkUserInput().rawValue) {
                      handOfUser = safeHandOfUser
                  }
              } catch {
                  print("잘못된 입력입니다. 다시 시도해주세요.")
                  continue outer
              }

safeHandOfUser의 접근경로를 보면:

RockPaperScissorsHand (rawValue: )

checkuserInput.rawValue()

인자값으로 try 한 뒤 에러를 catch 하는 방향으로 코드 진행이 이어진다.

아직은 이렇게 인자값을 받고 활용하는 것이 어색하지만 얼른 익숙해지도록 연습해야겠다🔥🔥🔥



개발자의 효율적인 문서 작성법

글쓰기의 포인트 - 구조화

  • 실습형 글 주제는 번호를 붙여서 작성하는 것이 좋다
  • 독자 대상에 따라서 최대한 구체화하는 것이 좋다.
  • 독자 대상이 초보자라면 트러블슈팅과 관련된 내용을 최대한 챙겨주는 것이 좋은 글이 된다.

글쓰기의 본질

  • 맞춤법과 오탈자 치명적인 것이 아니면 지장 없다.
  • 책 만드는 사람도 맞춤법 오류나 오탈자가 있다.
  • 개발자의 효율성도 중요하지만, 글은 여러 사람이 본다.
  • 알아야 할 부분은 정확하게 기술하고 핵심적인 부분만 얘기하는 습관을 가지자.
  • 무엇을 말하려고 하는지 대상만 명확하게 하자.

글이 잘 안 읽히는 원인!

  • 잘못 설명하면 안된다는 두려움

  • 구체적으로 설명하지 않는 습관

해결책

  • 코드와 기본 설명이 섞인 내용을 작성하자.

블로그 글쓰기

블로그 글 쓰기의 포인트 1

  • 특정 주제를 잡고 연재 형식으로 꾸준히 쓰는 방법이 있다.
  • 내 공부 기록을 꾸준히 남기는 방식이 있습니다.
  • 누군가에게 보여주는 글인가? 내가 참고하는 글인가?를 미리 생각하면 좋습니다.

블로그 글 쓰기의 포인트 2- 누군가에게 보여주는 글

  • 가능하면 경어체로 작성하는 것이 좋습니다.
  • 부연 설명할 다른 사람의 글 혹은 내 글을 미리 챙겨두면 좋습니다.
  • 특정 주제와 관련해 연재 형식으로 꾸준히 쓰는 방법이 좋습니다.
  • 카테고리 기반으로 정리하면 좋습니다.

블로그 글 쓰기의 포인트 3- 나만 보는 글

  • 어투는 큰 상관 없습니다.
  • 내가 알아볼만한 중요한 포인트를 잡고 쓰는 것이 좋습니다.
  • 내 공부 기록을 꾸준히 남기는 방식이 좋습니다.
  • 태그 기반으로 정리하는 것이 좋습니다.

블로그 플랫폼을 선택할 때 고려할 점

  • 본인이 운영하기 편한 블로그를 선택하자.

  • 단! 개발자 생활을 하려면 Markdown을 활용해서 문서 작업을 해야 하는 경우가 많다.

    그러니 Markdown이 지원되는 블로그 플랫폼을 사용하도록 하자.



문제점 / 고민한 점


class MukChiBa : RockPaperScissors {
    var currentTurn: String
    
    init(winner: String) {
        currentTurn = winner
    }

기존에는 currentTurn이라는 클래스 내 변수를 활용하여 case 별로 컴퓨터턴, 사용자턴과 같은 String으로 변화를 주면서 컴퓨터의 턴 그리고 사용자의 턴을 정해주는 로직을 짰었다.

그런데 해당 부분에서 currentTurn을 String으로 구분하면, 위혐성이 큰 것 같다라는 피드백을 받았다. 그래서 Neph의 하드캐리로 GameResult타입으로 설정하고 CustomStringConvertible 프로토콜을 정의하고 활용하여 아래와 같은 코드로 변경하였다.

enum GameResult: CustomStringConvertible {
        case userTurn
        case computerTurn
        case somebodyWin
        
        var description: String {
            switch self {
            case .userTurn:
                return "사용자"
            case .computerTurn:
                return "컴퓨터"
            default:
                return ""
            }
        }
    }

이 글을 쓸 때 까지도 왜 currentTurn을 String으로 구분하면 왜 위혐성이 클까? 의문이 들었다.

왜 그냥 String을 활용해서 쉽게 쉽게 가면 안되는 것일까...

해결 방법


그런데 이렇게 TIL을 쓰면서 조그만한 깨달음을 얻은 것 같다. 지금은 그저 가위바위보 그리고 묵찌빠에서 끝나지만 해당 게임을 추후에 글로벌런칭하고 멀티플레이까지 지원하면 코드가 훨씬 복잡해질 때 해당 변수는 노출이 쉽고 실수로 변경이 될 수 있다는 생각이 들었다. 만약 하나의 string값에 내가 사용자라 적지 않고 사룡자라 적은 뒤 글로벌 런칭을 할 경우 얼마나 창피할까 생각하니 아찔했다.

그렇기 때문에 미리 이렇게 enumcustomStringConvertible 을 활용하여 안전장치를 만들어 두는게 나을것 같다는 결론에 도달했다. 내가 도출해 낸 결론이 완전히 맞는 답은 아니기 때문에 아직 내 답에 만족하지는 않지만 그래도 올바른 방향으로 답을 도출 해 나아가는 것 같아서 기분은 좋다.

var currentTurn: GameResult
    
    init(rockPaperScissorsResult: RockPaperScissors.GameResult) {
        switch rockPaperScissorsResult {
        case .win:
            currentTurn = .userTurn
        case .lose:
            currentTurn = .computerTurn
        default:
            currentTurn = .computerTurn
        }
    }

currentTurnGameResult 타입으로 설정을하고 rockPaperScissorsResult 라는 생성자를 만든 뒤 switch 문을 활용해서 경우의 수를 설정하니 훨씬 더 안전해진 것을 볼 수 있다.

참고

개발자의 효율적인 문서 작성법 - 이중민

profile
james, the enthusiastic developer

0개의 댓글