-
Notifications
You must be signed in to change notification settings - Fork 0
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
[개발자 비상근무] 미니언 미션 제출합니다. #19
Open
gusah009
wants to merge
1
commit into
gusah009-main
Choose a base branch
from
gusah009/oncall
base: gusah009-main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,10 @@ | ||
package oncall | ||
|
||
import oncall.controller.OncallController | ||
import oncall.service.OncallService | ||
import oncall.view.InputView | ||
import oncall.view.OutputView | ||
|
||
fun main() { | ||
TODO("프로그램 구현") | ||
OncallController.run(InputView, OutputView, OncallService) | ||
} |
18 changes: 18 additions & 0 deletions
18
kotlin-oncall/src/main/kotlin/oncall/controller/OncallController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package oncall.controller | ||
|
||
import oncall.entity.Order | ||
import oncall.service.OncallService | ||
import oncall.view.InputView | ||
import oncall.view.OutputView | ||
|
||
object OncallController { | ||
|
||
fun run(inputView: InputView, outputView: OutputView, oncallService: OncallService) { | ||
val oncallDate = inputView.getOncallDate() | ||
val (weekdayOrder: Order, holidayOrder: Order) = inputView.getOrder() | ||
val oncallTable = oncallService.getOncallTable( | ||
oncallDate, weekdayOrder = weekdayOrder, holidayOrder = holidayOrder | ||
) | ||
outputView.printOncallTable(oncallTable) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package oncall.entity | ||
|
||
import oncall.exception.requireOncall | ||
|
||
const val MAX_NICKNAME_SIZE = 5 | ||
const val MIN_ORDER_MEMBER = 5 | ||
const val MAX_ORDER_MEMBER = 35 | ||
|
||
class Order(private val order: List<String>) { | ||
init { | ||
requireOncall(order.all { it.length <= MAX_NICKNAME_SIZE }) { "닉네임은 최대 ${MAX_NICKNAME_SIZE}자 여야 합니다." } | ||
requireOncall(order.size == order.distinct().size) { "중복된 이름이 있습니다." } | ||
requireOncall(order.size in MIN_ORDER_MEMBER..MAX_ORDER_MEMBER) { "비상 근무자는 ${MIN_ORDER_MEMBER}명 이상 ${MAX_ORDER_MEMBER}명 이하여야 합니다. 비상 근무자 수 : ${order.size}" } | ||
} | ||
|
||
private val size = order.size | ||
private var index = 0 | ||
private var queueMember: String? = null | ||
|
||
fun getNextTurnMember(previousMember: String?) = | ||
if (isQueueMemberTurn(previousMember)) { | ||
val nextTurnMember = queueMember | ||
queueMember = null | ||
nextTurnMember | ||
} else { | ||
getNextTurnMember(previousMember, this.getNextMember()) | ||
} | ||
|
||
private fun getNextTurnMember(previousMember: String?, nextMember: String) = | ||
if (previousMember == nextMember) { | ||
// 만약 다음 멤버와 바로 전 멤버가 같다면 큐에 넣고 그 다음 멤버를 순서로 올린다. | ||
queueMember = nextMember | ||
this.getNextMember() | ||
} else { | ||
nextMember | ||
} | ||
|
||
private fun isQueueMemberTurn(previousMember: String?) = queueMember != null && queueMember != previousMember | ||
|
||
private fun getNextMember() = this.order[(index++) % this.size] | ||
} |
15 changes: 15 additions & 0 deletions
15
kotlin-oncall/src/main/kotlin/oncall/exception/OncallException.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package oncall.exception | ||
|
||
const val ERROR_PREFIX = "[ERROR] " | ||
|
||
inline fun requireOncall(value: Boolean, lazyMessage: () -> Any) { | ||
if (!value) { | ||
throw OncallException(lazyMessage().toString()) | ||
} | ||
} | ||
|
||
class OncallException(message: String) : IllegalArgumentException() { | ||
override val message = ERROR_PREFIX + message | ||
} | ||
|
||
fun printlnOncallException(message: String) = println(ERROR_PREFIX + message) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package oncall.model | ||
|
||
import java.time.DayOfWeek | ||
import java.time.DayOfWeek.* | ||
import java.time.Month | ||
|
||
class OncallDate(val month: Month, private val startDayOfWeek: DayOfWeek) { | ||
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. JDK 표준 라이브러리가 있는지 몰랐네요..!! 유용하게 잘 쓰겠습니다~!! bb |
||
val monthDay = month.minLength() // 2월은 항상 28일 | ||
|
||
private val holidayMap = getHolidayMap(startDayOfWeek) | ||
|
||
private fun getHolidayMap(startDayOfWeek: DayOfWeek): Map<Int, Pair<DayOfWeek, DayType>> { | ||
val holidayMap = mutableMapOf<Int, Pair<DayOfWeek, DayType>>() | ||
for (day in 1..this.monthDay) { | ||
val dayOfWeek = startDayOfWeek.plus((day - 1).toLong()) | ||
holidayMap[day] = Pair(dayOfWeek, isHoliday(dayOfWeek, day)) | ||
} | ||
return holidayMap.toMap() | ||
} | ||
|
||
private fun isHoliday(dayOfWeek: DayOfWeek, day: Int) = when (dayOfWeek) { | ||
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. 리턴 타입이 Boolean 이라고 생각되게 만드는 메서드 명인 것 같습니다~! |
||
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> | ||
if (SPECIAL_HOLIDAY.contains(Pair(month.value, day))) { | ||
DayType.WEEKDAY_HOLIDAY | ||
} else { | ||
DayType.WEEKDAY | ||
} | ||
|
||
SATURDAY, SUNDAY -> DayType.HOLIDAY | ||
} | ||
|
||
operator fun get(day: Int) = holidayMap[day] | ||
|
||
companion object { | ||
val SPECIAL_HOLIDAY = listOf( | ||
Pair(1, 1), | ||
Pair(3, 1), | ||
Pair(5, 5), | ||
Pair(6, 6), | ||
Pair(8, 15), | ||
Pair(10, 3), | ||
Pair(10, 9), | ||
Pair(12, 25) | ||
) | ||
} | ||
} | ||
|
||
enum class DayType { | ||
WEEKDAY, | ||
WEEKDAY_HOLIDAY, | ||
HOLIDAY, | ||
; | ||
} |
36 changes: 36 additions & 0 deletions
36
kotlin-oncall/src/main/kotlin/oncall/service/OncallService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package oncall.service | ||
|
||
import oncall.entity.Order | ||
import oncall.exception.OncallException | ||
import oncall.model.DayType | ||
import oncall.model.OncallDate | ||
import java.time.DayOfWeek | ||
|
||
object OncallService { | ||
fun getOncallTable(oncallDate: OncallDate, weekdayOrder: Order, holidayOrder: Order): String { | ||
var previousMember: String? = null | ||
|
||
return buildString { | ||
for (day in 1..oncallDate.monthDay) { | ||
val (dayOfWeek, dayType) = oncallDate[day] ?: throw OncallException("존재하지 않는 날짜입니다: ${day}일") | ||
val nextMember = when (dayType) { | ||
DayType.WEEKDAY -> weekdayOrder.getNextTurnMember(previousMember) | ||
DayType.WEEKDAY_HOLIDAY, DayType.HOLIDAY -> holidayOrder.getNextTurnMember(previousMember) | ||
} | ||
previousMember = nextMember | ||
append("${oncallDate.month.value}월 ${day}일 ${dayOfWeek.toKorean()}${if (dayType == DayType.WEEKDAY_HOLIDAY) "(휴일)" else ""} ${nextMember}\n") | ||
} | ||
} | ||
} | ||
} | ||
|
||
private fun DayOfWeek.toKorean() = when (this) { | ||
DayOfWeek.MONDAY -> "월" | ||
DayOfWeek.TUESDAY -> "화" | ||
DayOfWeek.WEDNESDAY -> "수" | ||
DayOfWeek.THURSDAY -> "목" | ||
DayOfWeek.FRIDAY -> "금" | ||
DayOfWeek.SATURDAY -> "토" | ||
DayOfWeek.SUNDAY -> "일" | ||
else -> throw IllegalArgumentException() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package oncall.view | ||
|
||
import camp.nextstep.edu.missionutils.Console | ||
import oncall.entity.Order | ||
import oncall.exception.printlnOncallException | ||
import oncall.model.OncallDate | ||
import java.time.DayOfWeek | ||
import java.time.Month | ||
|
||
object InputView { | ||
fun getOncallDate() = tryGetUserInput { | ||
print("비상 근무를 배정할 월과 시작 요일을 입력하세요> ") | ||
Console.readLine().toOncallDate() | ||
} | ||
|
||
fun getOrder() = tryGetUserInput { | ||
print("평일 비상 근무 순번대로 사원 닉네임을 입력하세요> ") | ||
val weekdayOrder = Console.readLine().toOrder() | ||
print("휴일 비상 근무 순번대로 사원 닉네임을 입력하세요>") | ||
val holidayOrder = Console.readLine().toOrder() | ||
Pair(weekdayOrder, holidayOrder) | ||
} | ||
} | ||
|
||
private fun String.toOncallDate(): OncallDate { | ||
val (monthString, startDayOfWeekString) = this.split(",") | ||
return OncallDate(Month.of(monthString.toInt()), startDayOfWeekString.toDayOfWeek()) | ||
} | ||
|
||
private fun String.toDayOfWeek() = when (this) { | ||
"월" -> DayOfWeek.MONDAY | ||
"화" -> DayOfWeek.TUESDAY | ||
"수" -> DayOfWeek.WEDNESDAY | ||
"목" -> DayOfWeek.THURSDAY | ||
"금" -> DayOfWeek.FRIDAY | ||
"토" -> DayOfWeek.SATURDAY | ||
"일" -> DayOfWeek.SUNDAY | ||
else -> throw IllegalArgumentException() | ||
} | ||
|
||
private fun String.toOrder() = Order(this.split(",")) | ||
|
||
private fun <T> tryGetUserInput(inputFunction: () -> T): T { | ||
while (true) { | ||
try { | ||
return inputFunction() | ||
} catch (ignore: Exception) { | ||
printlnOncallException("유효하지 않은 입력 값입니다. 다시 입력해 주세요.") | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package oncall.view | ||
|
||
object OutputView { | ||
fun printOncallTable(oncallTable: String) { | ||
println(oncallTable) | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
식이 본문인 함수 사용 bb 인 것 같습니다~!