# 연락처 관리 프로그램 (console) 📞 > 2022.12.19 ~ 2012.12.30 이름, 나이, 연락처를 저장할 수 있는 연락처 관리 프로그램 📞 수정과 삭제는 안돼요 추가만 가능해요 --- ## 👀 Preview 전체 흐름 사진 ## Step 1 - 사용자 입력 및 검증 구현 `[이름]/[나이]/[연락처]` 혹은 `[이름] / [나이] / [연락처]`의 형태로 사용자 정보를 입력받아 검증하여 문제가 없을 경우 사용자 정보를 출력합니다. ### 플로우차트 <img width="50%" src="https://i.imgur.com/0xE0PuZ.png"> <br><br> > [문자열 검증] 입력받은 문자열이 "/"로 인해 각각 [이름], [나이], [연락처]로 나눠지는지 확인합니다. > > [이름 확인] 이름은 한글이 아닌 영어로만 입력이 가능하며 알파벳 사이에 공백은 제거한다. > > [나이 확인] 나이는 숫자로만 입력해야하며 세 자리수이하여야 합니다. > > [연락처 확인] 연락처는 '-'로 구분하며, 두 개 존재해야 합니다. 숫자는 9개 이상이어야 합니다. <img width="100%" src="https://i.imgur.com/FRZxSXO.png"> ### 테스트코드 문자열 검증, 이름 확인, 나이 확인, 연락처 확인을 위한 테스트 코드를 작성했습니다 ```swift func testSplit() throws { var splitted: (name: String, age: String, phoneNumber: String) = try split(input: "james/30/123-1234-1234") XCTAssertEqual(splitted.name, "james") XCTAssertEqual(splitted.age, "30") XCTAssertEqual(splitted.phoneNumber, "123-1234-1234") splitted = try split(input: "james / 30 / 123-1234-1234") XCTAssertEqual(splitted.name, "james") XCTAssertEqual(splitted.age, "30") XCTAssertEqual(splitted.phoneNumber, "123-1234-1234") splitted = try split(input: "james / 30 / ") XCTAssertEqual(splitted.name, "james") XCTAssertEqual(splitted.age, "30") XCTAssertEqual(splitted.phoneNumber, "") splitted = try split(input: "james/30/") XCTAssertEqual(splitted.name, "james") XCTAssertEqual(splitted.age, "30") XCTAssertEqual(splitted.phoneNumber, "") XCTAssertThrowsError(try split(input: "")) XCTAssertThrowsError(try split(input: "james/30")) XCTAssertThrowsError(try split(input: "james / 30 / 123-1234-1234 / 40")) XCTAssertThrowsError(try split(input: "james/30/123-1234-1234/40")) } func test이름() { XCTAssertEqual(try getName(input: "james"), "james") XCTAssertEqual(try getName(input: "jam es"), "james") XCTAssertThrowsError(try getName(input: "한글의이름")) XCTAssertThrowsError(try getName(input: "")) XCTAssertThrowsError(try getName(input: " james ")) XCTAssertThrowsError(try getName(input: " james")) XCTAssertThrowsError(try getName(input: "james ")) } func test나이() { XCTAssertEqual(try getAge(input: "23"), 23) XCTAssertEqual(try getAge(input: "999"), 999) XCTAssertEqual(try getAge(input: "0"), 0) XCTAssertThrowsError(try getAge(input: "000")) XCTAssertThrowsError(try getAge(input: "1234")) XCTAssertThrowsError(try getAge(input: "-3")) XCTAssertThrowsError(try getAge(input: "010")) XCTAssertThrowsError(try getAge(input: " 10 ")) XCTAssertThrowsError(try getAge(input: " 10")) XCTAssertThrowsError(try getAge(input: "10 ")) } func test전화번호() { XCTAssertNoThrow(try isValidPhoneNumber("05-434-2334")) XCTAssertThrowsError(try isValidPhoneNumber("054342334")) XCTAssertThrowsError(try isValidPhoneNumber("05-4342334")) XCTAssertThrowsError(try isValidPhoneNumber("05-4342334-")) XCTAssertThrowsError(try isValidPhoneNumber("-05434-2334")) XCTAssertThrowsError(try isValidPhoneNumber("05434--2334")) XCTAssertThrowsError(try isValidPhoneNumber("05-434-23-34")) XCTAssertThrowsError(try isValidPhoneNumber("05-434-234")) XCTAssertThrowsError(try isValidPhoneNumber("05 434 2334")) XCTAssertThrowsError(try isValidPhoneNumber("james")) XCTAssertThrowsError(try isValidPhoneNumber("전화번호부")) XCTAssertThrowsError(try isValidPhoneNumber("")) XCTAssertThrowsError(try isValidPhoneNumber(" 05-434-2334")) XCTAssertThrowsError(try isValidPhoneNumber("05-434-2334 ")) XCTAssertThrowsError(try isValidPhoneNumber(" 05-434-2334 ")) } ``` ## Step 2 - 사용자 메뉴 표기 구현 프로그램은 아래와 같은 동작을 하고 다시 메뉴를 출력합니다 - 1 입력 : `Step 1` 수행 - 2 입력 : 수행하지 않음 - 3 입력 : 수행하지 않음 - x 입력 : 프로그램 종료 - 그 외 입력 : 오류 출력 <br> ### 프로그램 동작 <img width="90%" src="https://i.imgur.com/dxrVKQo.png"> <br> <br> 반복적인 메뉴 출력을 하기 위해서 `while true`를 생각했으나 ContactManager에서 State의 `.continued` 와 `.quit` 의 값을 확인해서 반복문을 실행하도록 하는 방법을 알았습니다 ## Step 3 - 목록/검색 기능 ### 목록 기능 추가된 연락처를 아래와 같은 양식으로 출력합니다 <img width="80%" src="https://i.imgur.com/5if1QBQ.png"> <br> ### 검색 기능 이름을 입력받아 아래와 같은 양식으로 출력합니다 <img width="80%" src="https://i.imgur.com/v1Uwjlg.png"> <br> <br> 동일한 연락처는 제외시키기 위해 Set를 채택하여 `Set<Contact>` 타입의 `contacts`를 추가하였습니다. . `연락처 목록보기` 메뉴 실행시 contacts를 출력 하였고 `연락처 검색` 메뉴 실행시 입력받은 이름과 동일한 연락처를 출력합니다. ## 피드백을 통해 배운 점 - enum을 통해서 에러 출력만을 사용했었는데, error 타입에 대해서 배우고 do-catch를 사용하는 것까지 배웠습니다. - 메서드마다 에러를 던지고 최상위 메서드에서 do-catch 사용으로 에러를 파악하는 방법을 통해 좀 더 보기좋은 코드가 된 거 같습니다 - 하나의 메서드당 하나의 기능을 하는 게 이름을 정하는 것과 읽기 쉬운 코드가 되는 것을 배웠습니다.