-
Notifications
You must be signed in to change notification settings - Fork 37
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
은행 창구 관리 앱 [Step3] 이지, hong #92
base: d_Hong
Are you sure you want to change the base?
Changes from all commits
0f5b78c
d667351
2e54e5f
bba8e7d
ec07b48
90c5eab
beb38a9
a1d75de
0666b40
ae792bc
002d6e8
f40c08a
ce8a675
939cf90
fc55a43
7395e99
c35f050
8d79b57
285991c
7a7117c
09e4440
2e9d055
f7a9624
6fea095
9d3ae26
7310cda
a14c168
d4a1283
2bef8df
0953ff9
c013f5f
b53e24f
3814d57
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// | ||
// Bank.swift | ||
// BankManagerConsoleApp | ||
// | ||
// Created by dopamint on 1/31/24. | ||
// | ||
|
||
import Foundation | ||
|
||
final class Bank { | ||
|
||
private var banker = Banker() | ||
private var customerQueue = Queue<Customer>() | ||
private let depositSemaphore: DispatchSemaphore | ||
private let loanSemaphore: DispatchSemaphore | ||
private let group = DispatchGroup() | ||
|
||
init(depositBankerCount: Int, loanBankerCount: Int) { | ||
self.depositSemaphore = DispatchSemaphore(value: depositBankerCount) | ||
self.loanSemaphore = DispatchSemaphore(value: loanBankerCount) | ||
} | ||
|
||
func open() { | ||
let startTime = Date() | ||
Messages.openBank.printMessage() | ||
let numberOfCustomers = Int.random(in: 10...30) | ||
|
||
print("고객 수: \(numberOfCustomers)") | ||
setUpCustomerQueue(count: numberOfCustomers) | ||
|
||
while let customer = customerQueue.dequeue() { | ||
switch customer.taskType { | ||
case .deposit: | ||
serveCustomer(semaphore: depositSemaphore, customer: customer) | ||
case .loan: | ||
serveCustomer(semaphore: loanSemaphore, customer: customer) | ||
} | ||
} | ||
group.wait() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dispatchgroup에서의 enter, leave, enotify, wait에 대해서 각각 설명해주시고 이번 프로젝트에서는 왜 wait을 사용하셔서 구현했는지 이유를 설명해주세요 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
let endTime = Date() | ||
let elapsedTime = endTime.timeIntervalSince(startTime).formattedDecimal | ||
Messages.closeBank(customerCount: numberOfCustomers, totalTime: elapsedTime).printMessage() | ||
} | ||
|
||
private func serveCustomer(semaphore: DispatchSemaphore, customer: Customer) { | ||
DispatchQueue.global().async(group: group) { | ||
semaphore.wait() | ||
self.banker.processCustomer(customer) | ||
semaphore.signal() | ||
} | ||
} | ||
|
||
private func setUpCustomerQueue(count: Int) { | ||
for number in 1...count { | ||
let customer = Customer(number: number) | ||
customerQueue.enqueue(customer) | ||
} | ||
} | ||
} | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// | ||
// Banker.swift | ||
// BankManagerConsoleApp | ||
// | ||
// Created by dopamint on 1/31/24. | ||
// | ||
|
||
import Foundation | ||
|
||
final class Banker { | ||
|
||
func processCustomer(_ customer: Customer) { | ||
Messages.taskStart(number: customer.number, taskType: customer.taskType.description).printMessage() | ||
Thread.sleep(forTimeInterval: customer.taskType.taskTime) | ||
Messages.taskDone(number: customer.number, taskType: customer.taskType.description).printMessage() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// | ||
// Customer.swift | ||
// BankManagerConsoleApp | ||
// | ||
// Created by dopamint on 1/31/24. | ||
// | ||
final class Customer { | ||
let number: Int | ||
let taskType: TaskType | ||
|
||
init(number: Int) { | ||
self.number = number | ||
self.taskType = TaskType.random() | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// | ||
// WorkType.swift | ||
// BankManagerConsoleApp | ||
// | ||
// Created by dopamint on 2/1/24. | ||
// | ||
enum TaskType { | ||
case loan | ||
case deposit | ||
} | ||
|
||
extension TaskType { | ||
var description: String { | ||
switch self { | ||
case .loan: | ||
return "대출" | ||
case .deposit: | ||
return "예금" | ||
} | ||
} | ||
|
||
var taskTime: Double { | ||
switch self { | ||
case .loan: | ||
return 1.1 | ||
case .deposit: | ||
return 0.7 | ||
} | ||
} | ||
|
||
static func random() -> TaskType { | ||
return Bool.random() ? .loan : .deposit | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// | ||
// String+.swift | ||
// BankManagerConsoleApp | ||
// | ||
// Created by dopamint on 1/31/24. | ||
// | ||
|
||
extension Double { | ||
var formattedDecimal: String { | ||
return String(format: "%.2f", self) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// | ||
// Messages.swift | ||
// BankManagerConsoleApp | ||
// | ||
// Created by dopamint on 2/1/24. | ||
// | ||
|
||
enum Messages { | ||
case menu | ||
case exit | ||
case openBank | ||
case taskStart(number: Int, taskType: String) | ||
case taskDone(number: Int, taskType: String) | ||
case closeBank(customerCount: Int, totalTime: String) | ||
case menuError | ||
case numberError | ||
} | ||
|
||
extension Messages { | ||
func printMessage() { | ||
switch self { | ||
case .menu: | ||
print("1 : 은행계정\n2 : 종료") | ||
print("입력 : ", terminator: "") | ||
case .exit: | ||
print("프로그램을 종료합니다.") | ||
case .openBank: | ||
print("은행 문이 열렸습니다.") | ||
case .taskStart(let number, let taskType): | ||
print("\(number) 고객 \(taskType)업무 시작") | ||
case .taskDone(let number, let taskType): | ||
print("\(number) 고객 \(taskType)업무 종료") | ||
case .closeBank(let customerCount, let totalTime): | ||
print("업무가 마감되었습니다. 오늘 업무를 처리한 고객은 총 \(customerCount)명 이며, 총 업무시간은 \(totalTime)초 입니다.") | ||
case .menuError: | ||
print("올바른 메뉴를 선택해주세요.") | ||
case .numberError: | ||
print("숫자를 입력해주세요.") | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// | ||
// LinkedList.swift | ||
// BankManagerConsoleApp | ||
// | ||
// Created by yujaehong on 1/31/24. | ||
// | ||
|
||
final class LinkedList<T> { | ||
var front: Node<T>? | ||
var rear: Node<T>? | ||
|
||
init(front: Node<T>? = nil, rear: Node<T>? = nil) { | ||
self.front = front | ||
self.rear = rear | ||
} | ||
|
||
var first: T? { | ||
return front?.value | ||
} | ||
|
||
var isEmpty: Bool { | ||
return front == nil | ||
} | ||
} | ||
|
||
extension LinkedList { | ||
func append(_ value: T) { | ||
let newNode = Node(value) | ||
|
||
if isEmpty { | ||
front = newNode | ||
rear = front | ||
} else { | ||
rear?.next = newNode | ||
rear = newNode | ||
} | ||
} | ||
|
||
func removeFirst() -> T? { | ||
if front === rear { | ||
let result = front | ||
front = nil | ||
rear = nil | ||
return result?.value | ||
} | ||
guard let currentFront = front else { return nil } | ||
front = front?.next | ||
return currentFront.value | ||
} | ||
|
||
func removeAll() { | ||
front = nil | ||
rear = nil | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// | ||
// Node.swift | ||
// BankManagerConsoleApp | ||
// | ||
// Created by yujaehong on 1/31/24. | ||
// | ||
final class Node<T> { | ||
var value: T | ||
var next: Node? | ||
|
||
init(_ value: T, _ next: Node? = nil) { | ||
self.value = value | ||
self.next = next | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// | ||
// Queue.swift | ||
// BankManagerConsoleApp | ||
// | ||
// Created by yujaehong on 1/31/24. | ||
// | ||
|
||
final class Queue<T> { | ||
private var linkedList: LinkedList<T> | ||
|
||
init(linkedList: LinkedList<T> = LinkedList()) { | ||
self.linkedList = linkedList | ||
} | ||
} | ||
|
||
extension Queue { | ||
func enqueue(_ value: T) { | ||
linkedList.append(value) | ||
} | ||
|
||
|
||
func dequeue() -> T? { | ||
return linkedList.removeFirst() | ||
} | ||
|
||
func clear() { | ||
linkedList.removeAll() | ||
} | ||
|
||
func peek() -> T? { | ||
return linkedList.first | ||
} | ||
|
||
func isEmpty() -> Bool { | ||
return linkedList.isEmpty | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DispatchGroup을 Bank 타입 내부 변수로 선언해주신 이유는 무언인가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
작업별로 나뉘어진 메서드에서 접근하기 위해 Bank타입에 DispatchGroup를 선언했습니다.