Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[newJunsung] MyCreditManager 기능 구현 #23

Open
wants to merge 1 commit into
base: 2_NewJunsung
Choose a base branch
from

Conversation

newJunsung
Copy link

디렉터리 구조

  • main.swift
  • Controller
    • CreditManageController.swift
  • Global
    • ConsoleString.Swift
    • CreditError.swift
    • FileIO.swift
  • Model
    • Credit.Swift
    • CreditModel.Swift
  • View
    • CreditManageView

스스로 찾아본 것

  • MVC패턴
  • 정규표현식
  • enum과 enum내 함수 사용법
  • 예외처리, LocalizedError

적용 패턴: MVC

  • Model: 학생의 이름과 받은 성적들의 정보를 가지고 있다. 또한 프로세스 종료 시, 해당 정보를 credit.json파일에 저장한다.
  • View: 성적 관리 프로그램의 텍스트를 콘솔 창에 보여준다.
  • Controller: 뷰와 모델을 연결하며, 모델의 성적 정보를 가공하여 학생의 성적 평균을 보여준다.

정규표현식

CreditManageView.swift(39~46 lines)

private func getString() throws -> String {
        let regex = /^[0-9a-zA-Z+ ]*$/
        let opt = readLine()
        guard opt != "", let str = opt, (str.wholeMatch(of: regex) != nil) else {
            throw CreditError.inputError
        }
        return str
}

입력을 받는 조건이, 영어와 '+'였기 때문에 문자열을 언래핑 하는 과정에서 정규표현식을 적용할 수 있을 것이라 판단했다. 그래서 정규표현식을 활용하여 입력받은 문자열을 처리하는 함수를 만들었다.

enum과 enum내 함수 사용법

Credit.swift

enum Credit: String, Codable {
    case aP = "A+"
    case aZ = "A0"
    case bP = "B+"
    case bZ = "B0"
    case cP = "C+"
    case cZ = "C0"
    case dP = "D+"
    case dZ = "D0"
    case f = "F"
    
    func getScore() -> Double {
        switch self {
        case .aP:
            return 4.5
        case .aZ:
            return 4.0
        case .bP:
            return 3.5
        case .bZ:
            return 3.0
        case .cP:
            return 2.5
        case .cZ:
            return 2.0
        case .dP:
            return 1.5
        case .dZ:
            return 1.0
        case .f:
            return 0
        }
    }
}

성적 정보를 enum에 저장하였다. enum에 String(구조체)과 Codable(프로토콜)을 채택(상속)하였다. 왜냐하면 성적 정보(ex. "A+")를 받으면 그것을 enum화 해야했기 때문이다. Codable의 경우 Encodable과 Decodable을 합친 프로토콜로써, 데이터를 credit.json에 저장하고, 읽어오고자 채택했다.

예외처리와 LocalizedError

CreditError.swift

enum CreditError: Error {
    case inputError
    case studentAlreadyExsistsError(_ name: String)
    case studentNotFoundError(_ name: String)
    case subjectNotFoundError(_ subject: String)
    case subjectEmptyError(_ studentName: String)
}

extension CreditError: LocalizedError {
    public var errorDescription: String? {
        switch self {
        case .inputError:
            return "입력이 잘못되었습니다. 다시 확인해주세요"
        case .studentAlreadyExsistsError(let name):
            return "\(name)은 이미 존재하는 학생입니다. 추가하지 않습니다."
        case .studentNotFoundError(let name):
            return "\(name) 학생을 찾지 못했습니다."
        case .subjectNotFoundError(let name):
            return "\(name) 과목을 찾지 못했습니다."
        case .subjectEmptyError(let studentName):
            return "\(studentName) 학생은 아직 수강한 과목이 없습니다."
        }
    }
}

Error case는 입력이 잘못됐을 경우, 학생이 이미 존재할 경우, 학생이 없을 경우, 과목이 없을 경우, 학생의 성적이 없을 경우가 있다. 그 다음 error.localizedDescription을 사용하기 위해 LocalizedError를 사용했다. 이 프로토콜을 사용했기 때문에, 아래와 같이에서 예외처리를 편하게 할 수 있었다.

CreditManageView.swift (143~159 lines) - 예시

private func deleteCredit() {
        print(ConsoleString.deleteCredit)
        
        do {
            let strArr = try getString().split(separator: " ").map{ String($0) }
            if strArr.count != 2 {
                throw CreditError.inputError
            }
            
            let (student, subject) = (strArr[0], strArr[1])
            try cmController.delete(subject, of: student)
            print("\(student) 학생의 \(subject) 과목 성적이 삭제되었습니다.")
            print(CreditModel.shared.studentInfo)
        } catch {
            print(error.localizedDescription)
        }
}

@newJunsung newJunsung changed the base branch from main to 2_NewJunsung September 5, 2023 02:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant