diff --git a/Bank.swift b/Bank.swift index 48883ea23..e90bfee7a 100644 --- a/Bank.swift +++ b/Bank.swift @@ -9,28 +9,28 @@ import Foundation final class Bank { private var clients: [Client] = [] private var tellers: [Teller] = [] - private var finishedClientNumber = 0 + private var finishedClientCount = 0 private var businessTime: TimeInterval? - + func operateBank(teller: Int, client: [Client]) { let openTime = Date() initTellers(teller) - clients = client + clients = client.sorted() assignBusinessToTeller() businessTime = Date().timeIntervalSince(openTime) - Dashboard.printCloseMessage(finishedClientNumber, businessTime) + Dashboard.printCloseMessage(finishedClientCount, businessTime) closeBank() } - private func initTellers(_ number: Int) { - for windowNumber in 1...number { + private func initTellers(_ count: Int) { + for windowNumber in 1...count { tellers.append(Teller(windowNumber: windowNumber)) } } private func assignBusinessToTeller() { - let semaphore = DispatchSemaphore(value: 0) + let dispatchGroup = DispatchGroup() var isContinue = true while isContinue { @@ -41,20 +41,17 @@ final class Bank { } if teller.isNotWorking { let client = clients.removeFirst() - teller.workingQueue.async { - teller.handleBusiness(for: client) - semaphore.signal() - } - self.finishedClientNumber += 1 + teller.handleBusiness(for: client, withDispatchGroup: dispatchGroup) + self.finishedClientCount += 1 } } } - for _ in 0.. Bool { + return lhs.priority < rhs.priority + } + + static func == (lhs: Client, rhs: Client) -> Bool { + return lhs.priority == rhs.priority } } diff --git a/BankManagerConsoleApp/BankManagerConsoleApp/Dashboard.swift b/BankManagerConsoleApp/BankManagerConsoleApp/Dashboard.swift index 22cc1a396..694b5f503 100644 --- a/BankManagerConsoleApp/BankManagerConsoleApp/Dashboard.swift +++ b/BankManagerConsoleApp/BankManagerConsoleApp/Dashboard.swift @@ -7,22 +7,22 @@ import Foundation -class Dashboard { +struct Dashboard { static func printMenu() { print(Menu.description, terminator: " ") } - static func printStatus(for client: Client, about message: Message) { - let message = String(format: message.rawValue, client.waitingNumber) + static func printStatus(for client: Client, about message: String) { + let message = String(format: message, client.waitingNumber, "\(client.priority)", "\(client.businessType)") print(message) } - static func printCloseMessage(_ number: Int, _ time: TimeInterval?) { + static func printCloseMessage(_ count: Int, _ time: TimeInterval?) { guard let time = time else { - print(BankError.unknown.description) + print("\(BankError.unknown)") return } - let message = String(format: Message.close.rawValue, number, time) + let message = String(format: Message.close, count, time) print(message) } } diff --git a/BankManagerConsoleApp/BankManagerConsoleApp/Enum.swift b/BankManagerConsoleApp/BankManagerConsoleApp/Enum.swift index 3dc67ee44..1bc12495b 100644 --- a/BankManagerConsoleApp/BankManagerConsoleApp/Enum.swift +++ b/BankManagerConsoleApp/BankManagerConsoleApp/Enum.swift @@ -18,24 +18,36 @@ enum Menu: String { """ } -enum Message: String { - case close = "업무가 마감되었습니다. 오늘 업무를 처리한 고객은 총 %d명이며, 총 업무시간은 %.2f초입니다." - case tellerStart = "%d번 고객 업무 시작" - case tellerFinish = "%d번 고객 업무 완료" +enum Message { + static let close = "업무가 마감되었습니다. 오늘 업무를 처리한 고객은 총 %d명이며, 총 업무시간은 %.2f초입니다." + static let tellerStart = "%d번 %@고객 %@업무 시작" + static let tellerFinish = "%d번 %@고객 %@업무 완료" } -enum BusinessType { - case normal +enum BusinessType: CaseIterable, CustomStringConvertible { + case deposit + case loan var neededTime: TimeInterval { switch self { - case .normal: + case .deposit: return 0.7 + case .loan: + return 1.1 + } + } + + var description: String { + switch self { + case .deposit: + return "예금" + case .loan: + return "대출" } } } -enum BankError: Error { +enum BankError: Error, CustomStringConvertible { case wrongInput case unknown diff --git a/BankManagerConsoleApp/BankManagerConsoleApp/Teller.swift b/BankManagerConsoleApp/BankManagerConsoleApp/Teller.swift index 4dd014a10..f63af846d 100644 --- a/BankManagerConsoleApp/BankManagerConsoleApp/Teller.swift +++ b/BankManagerConsoleApp/BankManagerConsoleApp/Teller.swift @@ -20,13 +20,14 @@ final class Teller { workingQueue = DispatchQueue(label: "\(windowNumber)") } - func handleBusiness(for client: Client) { - let needTimeToWork = client.businessType.neededTime - + func handleBusiness(for client: Client, withDispatchGroup group: DispatchGroup) { isWorking = true - Dashboard.printStatus(for: client, about: .tellerStart) - Thread.sleep(forTimeInterval: needTimeToWork) - Dashboard.printStatus(for: client, about: .tellerFinish) - isWorking = false + + workingQueue.async(group: group) { + Dashboard.printStatus(for: client, about: Message.tellerStart) + Thread.sleep(forTimeInterval: client.businessType.neededTime) + Dashboard.printStatus(for: client, about: Message.tellerFinish) + self.isWorking = false + } } } diff --git a/BankManagerConsoleApp/BankManagerConsoleApp/main.swift b/BankManagerConsoleApp/BankManagerConsoleApp/main.swift index 80d6c8f7c..16258eaed 100644 --- a/BankManagerConsoleApp/BankManagerConsoleApp/main.swift +++ b/BankManagerConsoleApp/BankManagerConsoleApp/main.swift @@ -6,47 +6,26 @@ import Foundation -private func randomNumber(from minNumber: Int = 0, to maxNumber: Int) -> Int { - return Int.random(in: minNumber...maxNumber) -} - -private func initClients(_ number: Int) -> [Client]? { - var clients: [Client] = [] - - for waitingNumber in 1...number { - clients.append(Client(waitingNumber: waitingNumber)) - } - return clients -} - -private func main() { +func main() { let bank = Bank() - let tellerNumber = 3 - let maxClientNumber = 30 - let minClientNumber = 10 + let tellerCount = 3 + let maxClientCount = 30 + let minClientCount = 10 var isContinue = true - func initClients(_ number: Int) -> [Client] { - var clients: [Client] = [] - - for waitingNumber in 1...number { - clients.append(Client(waitingNumber: waitingNumber)) - } - return clients - } - while isContinue { Dashboard.printMenu() guard let input = readLine(), let command = Menu(rawValue: input) else { - print(BankError.wrongInput.description) + print("\(BankError.wrongInput)") continue } switch command { case .start: - let clients = initClients(randomNumber(from: minClientNumber, to: maxClientNumber)) - bank.operateBank(teller: tellerNumber, client: clients) + let randomNumber = Int.random(in: minClientCount...maxClientCount) + let clients = Clients.init(count: randomNumber) + bank.operateBank(teller: tellerCount, client: clients.list) case .end: isContinue = false }