๋ค์ด๊ฐ๋ฉฐ
๋ฒ์จ ํญํด๋ฅผ ์์ํ๊ณ 10์ฃผ ๊ณผ์ ์ ์ ๋ฐ ์ง์ ์ ๋์ฐฉํ๋ค. ๋ณธ์
๊ณผ ํจ๊ป ๊ฐ๋ ๋์ ๊ณผ์ ๋ฅผ ์ํํ๋ ๊ฒ์ด ์ฝ์ง๋ ์์์ง๋ง, ์ ๋ฐ์ด ์ง๋ฌ๋ค๋ ์ ์์ ๋จ์ ์ ๋ฐ๋ ๊ธ๋ฐฉ ์ ํด๋ผ ์ ์์ ๊ฒ ๊ฐ๋ค๋ ์๊ฐ์ด ๋ ๋ค. ์ง๋ 5์ฃผ ๋์ ์ฐ๋ฆฌ ํ 5๋ช
์ค 3๋ช
์ด ์ดํํ๋ค. ๋๋ถ๋ถ์ด ๋ณธ์
๋๋ฌธ์ ๊ณผ์ ์ ์ง์คํ๊ธฐ ์ด๋ ค์ ๊ธฐ ๋๋ฌธ์ด์๋ค. ๋คํํ ๋์ ๊ฒฝ์ฐ ํ์ฌ๊ฐ ๋ฐ์ ์์ฆ์ด ์๋์ด์ (๋ฌผ๋ก ๋ฐ์์ง ์์๋ ํ๋ค์ง๋ง) ์ฌ๊ธฐ๊น์ง ๋ฒํธ ์ ์์๋ค.
์ง๋ 3์ฃผ ๋์ ๊ณผ์ ๋ฅผ ์งํํ๋ฉด์ ๋ง์ ๊ฒ์ ๋ฐฐ์ฐ๊ณ ๊ฒฝํํ๋ค. ์ผ ๋๋๊ณ ์๋ฒฝ 2~3์๊น์ง ๊ณผ์ ๋ฅผ ํ๋ฉฐ ํผ๊ณค์ ์ง์ณ ์์์ง๋ง, ๋๋ถ์ ๋จ๊ธฐ๊ฐ์ ํฐ ์ฑ์ฅ์ ์ด๋ฃฌ ๊ฒ ๊ฐ๋ค. ์ด๋ฒ ํ๊ณ ์์๋ ํ๋ก์ ํธ Chapter 2(3~5์ฃผ์ฐจ)๋ฅผ ์งํํ๋ฉด์ ๋ฐฐ์ด ์ ๋ค๊ณผ, ์ฌ์ ํ ๊ณ ๋ฏผ ์ค์ธ ๋ถ๋ถ๋ค์ ์ ๋ฆฌํด๋ณด๋ ค๊ณ ํ๋ค.
์๋๋ฆฌ์ค
์ด๋ฒ ํ๋ก์ ํธ๋ ์ฝ์ํธ ์ข์ ์์ฝ ์๋น์ค๋ฅผ ๊ฐ๋ฐํ๋ ๊ฒ์ด์๋ค. ์์ฝ ์์คํ
์์๋ ๋๊ธฐ์ด ๊ด๋ฆฌ๊ฐ ๋งค์ฐ ์ค์ํ ์์๊ณ , ์ฌ๋ฌ ์ฌ์ฉ์๊ฐ ๋์์ ์ข์์ ์์ฝํ๋ ค๊ณ ํ ๋ ๊ณต์ ํ๊ฒ ์์ฝ์ ์ฒ๋ฆฌํ๊ณ ์ข์ ์ํ๋ฅผ ์ ์ ํ๊ฒ ๊ด๋ฆฌํ๋ ๊ฒ์ด ํต์ฌ์ด์๋ค. ๊ฐ ๊ธฐ๋ฅ๋ง๋ค์ ๋น์ฆ๋์ค ๋ก์ง์ด ์๊ฐ๋ณด๋ค ๋ณต์กํ๊ฒ ์ฝํ ์์๊ณ , ๋๋ถ์ ์ฌ๋ฌ ๊ฐ์ง ๊ณ ๋ฏผ๊ณผ ์๋ก์ด ์ ๊ทผ ๋ฐฉ์์ ์๋ํ๋ฉด์ ๋ฌธ์ ํด๊ฒฐ์ ๋ํ ์ ๊ทผ ๋ฐฉ๋ฒ์ด ํ์ฅ๋ ๋๋์ ๋ฐ์๋ค.
๋ชฉํ
์ด๋ฒ ํ๋ก์ ํธ์ ์ฃผ์ ๋ชฉํ๋ ์๋์ ๊ฐ๋ค.
1. ๋๋ฉ์ธ์ ๋ํ ์ดํด
์ฝ์ํธ
, ์์ฝ
, ๊ฒฐ์
๋ผ๋ ๋๋ฉ์ธ์ ๋ํ ์ดํด๊ฐ ํ์ํ๋ค. ์๋๋ฆฌ์ค๋ฅผ ๋ฐ์ ํ ์ ์ผ ๋จผ์ ์๊ตฌ์ฌํญ์ ๋ฆฌ์คํธ๋ก ์์ฑํ๊ณ , ๋๋ฉ์ธ ๋ณ๋ก ๋ฌถ์ด ์ด๋ค ๊ธฐ๋ฅ์ ๊ตฌํํด์ผ ํ ์ง์ ๋ํด ๊ณ ๋ฏผํ๋ค. ์ด๋ฅผ ํตํด ๊ฐ ๊ธฐ๋ฅ์ด ์ค์ ๋๋ฉ์ธ์์ ์ด๋ป๊ฒ ์๋ํ๋์ง๋ฅผ ์ดํดํ๊ณ , ๋น์ฆ๋์ค ๋ก์ง์ ์ค๊ณํ๊ณ ๊ตฌํํ๋ค.
2. ๋น์ฆ๋์ค ๋ก์ง์ ๋ช ํํ ๋ถ๋ฆฌ
์ ์ง๋ณด์์ฑ์ ๋์ด๊ธฐ ์ํด ํด๋ฆฐ & ๋ ์ด์ด๋ ์ํคํ
์ฒ์ ๋ฐ๋ผ ๋น์ฆ๋์ค ๋ก์ง์ ๋ช
ํํ๊ฒ ๋ถ๋ฆฌํ๊ณ , ๊ฐ ๊ณ์ธต์ ์ญํ ์ ์ ์ํ๋ค. ํ์์ ๋ ์ด์ด๋ง ์์กดํ๋ ๋จ๋ฐฉํฅ ์์กด์ฑ์ ์ ์งํ๋ ค๊ณ ๋
ธ๋ ฅํ๋ค. ๋ก์ง์ด ๋ณต์กํด์ง์๋ก ์ญํ ๊ณผ ์ฑ
์์ ๋ช
ํํ๊ฒ ๋ถ๋ฆฌํ์ฌ ๊ฐ์ฒด์งํฅ์ ์ ๊ทผ ๋ฐฉ์์ผ๋ก ์์ฑํ๋ค.
3. ๋์์ฑ ๋ฌธ์ ํด๊ฒฐ
์ข์ ์์ฝ ์ ์ฌ๋ฌ ์ฌ์ฉ์๊ฐ ๋์์ ์ ๊ทผํ ์ ์๋ ์ํฉ์์ ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ์ ์ ์งํ๋ฉฐ ์ถฉ๋์ ๋ฐฉ์งํ๋ ๊ฒ์ด ๋ชฉํ์๋ค. ๋๋ฉ์ธ ํน์ฑ์ ์ดํดํ๊ณ , ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ๋ฐฉ๋ฒ์ ๊ณ ๋ฏผํ๋ค. ์๋ฅผ ๋ค์ด, ์ ์ ์ ํฌ์ธํธ ์ถฉ์ ๋ก์ง์์๋ ์ถฉ์ ์ ๋ํ ์์ฐจ ๋ณด์ฅ์ด ํ์ํ์ง ์๋ค๊ณ ํ๋จํ์ฌ ๋๊ด์ ๋ฝ์ ์ฌ์ฉํ๊ณ , ์คํจํ ์ค๋ ๋์ ๋ํด์๋ ์ฌ์๋ํ์ง ์๊ณ ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ํ๋๋ก ๊ตฌํํ๋ค.
4. ์๋ก์ด ๊ธฐ์ ์ต๋
์ฝํ๋ฆฐ๊ณผ JPA ๊ฐ์ ์๋ก์ด ๊ธฐ์ ์ ์ค๋ฌด์ ์ ์ฉํ ์ ์๋ ์์ค์ผ๋ก ํ์ตํ๊ณ ํ์ฉํ๋ ๊ฒ๋ ์ค์ํ ๋ชฉํ ์ค ํ๋์๋ค.
๋ฌธ์ ๋ฐ ์๋, ํด๊ฒฐ ๊ณผ์
1. ์ํ์ค ๋ค์ด์ด๊ทธ๋จ ์์ฑ
์ด๋ฒ์ ์ฒ์์ผ๋ก ์ํ์ค ๋ค์ด์ด๊ทธ๋จ์ ์์ฑํ๋ค. ๋ณต์กํ ๋น์ฆ๋์ค ๋ก์ง์ ์๊ฐ์ ์ผ๋ก ํํํ๋ฉด์ ์ ์ฒด ํ๋ฆ์ ๋ ์ ์ดํดํ ์ ์์๊ณ , ํ์๋ค๊ณผ์ ์ปค๋ฎค๋์ผ์ด์
์๋ ํฐ ๋์์ด ๋์๋ค. ์ํ์ค ๋ค์ด์ด๊ทธ๋จ์ ํตํด ๊ฐ ์ปดํฌ๋ํธ์ ์ํธ์์ฉ๊ณผ ๋ฐ์ดํฐ ํ๋ฆ์ ๋ช
ํํ๊ฒ ์๊ฐํํ ์ ์์๊ณ , ์ฝ๋ ๊ตฌํ์ ์์๋๋ ์๊ฐ์ ๋ํญ ์ค์ผ ์ ์์๋ค. ์์ผ๋ก๋ ํ๋ก์ ํธ๋ฅผ ์งํํ ๋๋ง๋ค ์ํ์ค ๋ค์ด์ด๊ทธ๋จ์ ์ ๊ทน์ ์ผ๋ก ํ์ฉํ ๊ณํ์ด๋ค.
์ํ์ค ๋ค์ด์ด๊ทธ๋จ ์์ฑ GitHub ๋งํฌ
2. ๋๊ธฐ์ด ์์คํ ์ ๊ตฌํ๊ณผ ๋์์ฑ ์ฒ๋ฆฌ
๋๊ธฐ์ด ์์คํ
์ ์ด๋ป๊ฒ ๊ตฌํํ ์ง, ํนํ ์ฌ๋ฌ ์ฌ์ฉ์๊ฐ ๋์์ ์์ฝ์ ์๋ํ ๋ ๋์์ฑ ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ํด๊ฒฐํ ์ง๊ฐ ํฐ ๊ณ ๋ฏผ์ด์๋ค. Redis ๋์ RDB๋ฅผ ์ฌ์ฉํด ๋๊ธฐ์ด์ ๊ตฌํํ๊ณ , ๋น๊ด์ ๋ฝ๊ณผ ๋๊ด์ ๋ฝ์ ์ํฉ์ ๋ง๊ฒ ์ ์ฉํด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค. ์ ์ ์ ํฌ์ธํธ ์ถฉ์ ๋ก์ง์๋ ๋๊ด์ ๋ฝ์ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ถํ๋ฅผ ์ค์ด๋ฉด์๋ ์ผ๊ด์ฑ์ ์ ์งํ๊ณ , ์ข์ ์์ฝ์ด๋ ๊ฒฐ์ ๋ฑ์ ์ค์ํ ๋น์ฆ๋์ค ๋ก์ง์๋ ๋น๊ด์ ๋ฝ์ ์ฌ์ฉํด ์์๊ฐ ๋ณด์ฅ๋๊ณ ์ผ๊ด์ฑ ์๋ ๊ฒฐ๊ณผ๋ฅผ ์๋ตํ๋๋ก ์์ฑํ๋ค. ์ด ๊ณผ์ ์์ ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ๋ค์ํ ๋ฐฉ๋ฒ๋ค์ ํ์ตํ ์ ์์๋ค.
๋์์ฑ ์ฒ๋ฆฌ ์ฝ๊ฒ ์ดํดํ๊ธฐ
3. ํ ์คํธ ์ฝ๋ ์์ฑ
์ข์ ํ ์คํธ ์ฝ๋๋ ๋ฌด์์ผ๊น์ ๋ํด ๋ง์ ๊ณ ๋ฏผ์ ํ๋ค. ๋จ์ํ ๊ธฐ๋ฅ์ด ์ ๋์ํ๋์ง๋ง ํ์ธํ๋ ๊ฒ์ด ์๋๋ผ, ๋ค์ํ ์คํจ ์๋๋ฆฌ์ค๋ฅผ ์ปค๋ฒํ ์ ์๋ ํ ์คํธ๋ฅผ ์์ฑํ๋ ค๊ณ ๋ ธ๋ ฅํ๋ค. ์ฃ์ง ์ผ์ด์ค์ ์คํจ ์๋๋ฆฌ์ค๋ฅผ ํฌ๊ดํ๋ ํ ์คํธ๋ฅผ ํตํด ์๋น์ค์ ์์ ์ฑ์ ๋ณด์ฅํ๊ณ ์ ํ๋ค.
4. ๋๊ธฐ์ด ํ ํฐ ๊ด๋ฆฌ
๋๊ธฐ์ด ํ ํฐ ๊ด๋ฆฌ ๋ฐฉ๋ฒ์ผ๋ก ์ ์ ์ธ์ฆ๊ณผ ๋๊ธฐ์ด ํ ํฐ์ ๊ด๊ณ๋ฅผ ๋ถ๋ฆฌํ๊ณ ์ธ์ ๊ธฐ๋ฐ์ผ๋ก ํ ํฐ์ ์ ์ฅํ๋ ๋ฐฉ์์ ์๋ํ๋ค. ์ด๋ ์ํ์์ ๋๊ธฐํ๋ฅผ ๋ฐ๋ฏ์ด ๋ค๋ฅธ ์ ์ ์๊ฒ ๋๊ธฐํ๋ฅผ ๋๊ฒจ์ค ์ ์๋ ๊ตฌ์กฐ๋ก ์ค๊ณํ๋ค. ์ด๋ฅผ ํตํด ๋ ์ ์ฐํ ์์คํ ์ ๊ตฌ์ถํ ์ ์์๋ค.
์๋์ ๊ฐ์ด user
์ ๋ํ ์๋ณ์๋ฅผ ์ ๊ฑฐํ๊ณ , token์ผ๋ก ๋๊ธฐ์ด์ ๋ํ ์ํ๋ง์ ๊ด๋ฆฌํ๋๋ก ํ๋ค.
@Entity
class WaitingQueue(
val scheduleId: Long,
val token: String,
status: QueueStatus,
expiresAt: LocalDateTime?,
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0L,
) : BaseEntity() {
@Enumerated(EnumType.STRING)
var status: QueueStatus = status
protected set
var expiresAt: LocalDateTime? = expiresAt
protected set
fun expire() {
status = QueueStatus.EXPIRED
}
fun activate(expireMinutes: Long) {
this.status = QueueStatus.ACTIVE
this.expiresAt = LocalDateTime.now().plusMinutes(expireMinutes)
}
}
5. ์ฝํ๋ฆฐ์์์ JPA ์ฌ์ฉ
์ฝํ๋ฆฐ์ผ๋ก JPA๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ ์๋ก์ด ๋์ ์ด์๋ค. ํนํ ์ํฐํฐ ์ ์ธ ๋ฐฉ์์ ๋ํด ์ธํฐ๋ท์ ๊ฒ์ํด๋ณด๋ฉด ์๊ฒฌ์ด ๋ถ๋ถํ๋๋ฐ, ์ฝ์น๋์ ์ค๋ฌด ๊ฒฝํ์ ๋ฐ๋ฅธ ์กฐ์ธ์ ๋ฐํ์ผ๋ก ID
๋ฅผ null
๋์ 0
์ผ๋ก ์ด๊ธฐํํ๋ ๋ฐฉ์์ ์ ํํ๋ค. ์ด๋ฅผ ํตํด !!
์ฐ์ฐ์ ์ฌ์ฉ์ ์ค์ผ ์ ์์๊ณ , JPA์์ ์ํฐํฐ๋ฅผ ์ ์ฅํ ๋๋ ๋ ์์ฐ์ค๋ฝ๊ฒ ๋์ํ๊ฒ ๋์๋ค.
์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ์์ผ๋ก ๊ตฌํํ๋ค.
@Entity
class Concert(
title: String,
duration: Int,
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0L,
) : BaseEntity() {
var title: String = title
protected set
var duration: Int = duration
protected set
}
6. ์ ํ๋ฆฌ์ผ์ด์ ๊ณ์ธต ๊ด๋ฆฌ
์ ํ๋ฆฌ์ผ์ด์
๊ณ์ธต์ ๊ฐ๋ฅํ ์๊ฒ ์ ์งํ๊ณ , ๋น์ฆ๋์ค ๋ก์ง์ ๋๋ฉ์ธ์์ ๋๊ป๊ฒ ์ ์งํ๋ ค๊ณ ํ๋ค. ๋ ์ํฐํฐ๋ฅผ ์ง์ ๋๊ฒจ๋ฐ๋ ๋์ POJO
๊ฐ์ฒด๋ฅผ ์ฃผ๊ณ ๋ฐ์ผ๋ฉฐ, ์ํฐํฐ ๋ณ๊ฒฝ์ ๋ด๋ถ์์๋ง ์ด๋ฃจ์ด์ง๋๋ก ํ๋ค.
์๋ฅผ ๋ค์ด, ์์ฝ ๊ฐ๋ฅ ์ข์ ์์ ๋ํ ํ๋ ๊ฐ ๋ณ๊ฒฝ ์ ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ์์ผ๋ก ๋ฉ์๋๋ฅผ ์์ฑํ๋ค.
@Entity
class ConcertSchedule(
val concertId: Long,
startTime: LocalDateTime,
totalSeats: Int,
availableSeats: Int,
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0L,
) : BaseEntity() {
...
fun occupySeat() {
if (availableSeats <= 0) {
throw CoreException(
errorType = ErrorType.SEAT_UNAVAILABLE,
message = "No available seats left to reserve.",
)
}
this.availableSeats -= 1
}
...
}
๋ฉ์๋๋ช
์ ๊ฐ๋ฅํ ๋๋ฉ์ธ ๊ด์ ์์์ ํ์๋ช
์ผ๋ก ๋ช
ํํ๊ฒ ํํํ๋ค. ์๋ฅผ ๋ค์ด, decrementAvailableSeats()
๋์ occupySeat()
๊ฐ์ ํ์๋ช
์ ์ฌ์ฉํจ์ผ๋ก์จ ์ฝ๋์ ๊ฐ๋
์ฑ์ ๋์๊ณ , ์ฝ๋์ ์๋ฏธ๋ฅผ ๋ ๋ช
ํํ๊ฒ ์ ๋ฌํ ์ ์์๋ค.
7. ์๋ฌ ํธ๋ค๋ง
๊ธฐ์กด์๋ ๊ฐ๋ณ์ ์ผ๋ก ์ปค์คํ ์์ธ๋ฅผ ๋ง๋ค์ด ์ฌ์ฉํ์ง๋ง, ๊ด๋ฆฌ๊ฐ ์ด๋ ค์์ง๋ ๋ฌธ์ ์ ์ด ์์๋ค.
์ด๋ฅผ ๊ฐ์ ํ๊ธฐ ์ํด ErrorType
์ ์์ฑํ๊ณ , ๊ฐ ์๋ฌ ์ฝ๋, ๋ฉ์์ง, ๋ก๊ทธ ๋ ๋ฒจ์ ๋ถ์ฌํด ํ๋์ ์ปค์คํ
์์ธ๋ก ์ฒ๋ฆฌํ๋ค.
์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ด ErrorType
์ ์ ์ํ๋ค.
enum class ErrorType(val code: ErrorCode, val message: String, val logLevel: LogLevel) {
// common
SYSTEM_FAILURE(SYSTEM_ERROR, "System encountered an unexpected error.", ERROR),
TOKEN_EXPIRED(AUTHORIZATION_ERROR, "The token has expired.", WARN),
// WaitingQueue
INVALID_TOKEN(VALIDATION_ERROR, "Invalid or missing token.", WARN),
QUEUE_ALREADY_EXISTS(QUEUE_ERROR, "A queue already exists for this token.", WARN),
NO_QUEUE_FOUND(QUEUE_ERROR, "No queue found for the given token.", WARN),
// Concert
...
// User
...
// Payment
...
}
class CoreException(
val errorType: ErrorType,
val details: Any? = null,
message: String = errorType.message,
) : RuntimeException(message)
์ด ๋ฐฉ์ ๋๋ถ์ ์์ธ ์ฒ๋ฆฌ์ ๋ํ ์ ์ง๋ณด์ ํฅ์๊ณผ ์ผ๊ด์ฑ์ ์ ์งํ ์ ์์๋ค.
์์ผ๋ก ๊ฐ์ ํด๋๊ฐ ์
1. ๋๊ธฐ์ด ์์คํ ์ ๊ณ ๋ํ
ํ์ฌ๋ RDB์ ์ ์ฅ๋ ํ ํฐ์ ์ฌ์ฉํด ๋๊ธฐ์ด์ ๊ด๋ฆฌํ๊ณ ์์ง๋ง, ์์ผ๋ก๋ ์ฑ๋ฅ ๋ฉด์์ ๋ ๋น ๋ฅธ ์๋ต ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๋๋ก ๊ฐ์ ํด๋ณด๊ณ ์ ํ๋ค. ์ด๋ฅผ ์ํด Redis์ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ๊ธฐ๋ฐ ๋ฐ์ดํฐ ์ ์ฅ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๊ณ ๋ ค ์ค์ด๋ค.
2. ํ ์คํธ ์์ฑ
์ด๋ฒ ๊ณผ์ ์์ ํ
์คํธ ์ฝ๋๋ฅผ ์ด 77๊ฐ ์์ฑํ๋ค. ์ค๋ฌด์์ ํ
์คํธ ์ฝ๋๋ฅผ ์์ฑํด๋ณธ ๊ฒฝํ์ด ์์ด์ ์ด ์ซ์๊ฐ ๋ง์์ง ์ ์์ง๋ ๋ชจ๋ฅด๊ฒ ์ง๋ง, ํ
์คํธ๋ฅผ ์์ฑํ๋ฉด์ ์ค์ํ ์ ์ ๊นจ๋ฌ์๋ค. ํ
์คํธ ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ์ฑ์ฐ๊ธฐ ์ํ ํ
์คํธ ์ฝ๋๊ฐ ์๋, ์ค์ ๋ก ์์คํ
์ ์์ ์ฑ์ ๋ณด์ฅํ๋ ํ
์คํธ ์ฝ๋๋ฅผ ์์ฑํด์ผ ํ๋ค๋ ๊ฒ์ด๋ค.
๋จ์ ํ
์คํธ๋ ํ์ดํธ๋ฐ์ค ํ
์คํธ๋ก ๋ด๋ถ ๋ก์ง์ ๊ฒ์ฆํ๋ ๋ฐ ์ง์คํด์ผ ํ๋ฉฐ, ํตํฉ ํ
์คํธ๋ ๋ธ๋๋ฐ์ค ํ
์คํธ๋ก ์ธ๋ถ์์์ ์ผ๊ด์ฑ์ ๊ฒ์ฆํด์ผ ํ๋ค. ์ด๋ฌํ ์ฃผ์ ๋ฅผ ๋ฒ์ด๋๋ ํ
์คํธ๋ ์ง์ํด์ผ ํ๋ค๊ณ ์๊ฐํ๋ค. ๋ค์ํ ์ฃ์ง ์ผ์ด์ค๋ฅผ ํ
์คํธํ์ฌ ์์คํ
์ ์์ ์ฑ์ ๋ณด์ฅํด์ผ ํ๋ค.
3. ์๋น์ค์ ํ์ฅ์ฑ์ ๊ณ ๋ คํ ์ค๊ณ
ํ์ฌ์ ๊ตฌ์กฐ๊ฐ ์ด๋ ์ ๋์ ํธ๋ํฝ์ ์ฒ๋ฆฌํ ์ ์์์ง, ํฅํ ํธ๋ํฝ ์ฆ๊ฐ์ ์ด๋ป๊ฒ ๋์ํ ์ ์์์ง๋ฅผ ๊ณ ๋ คํด๋ณด๊ณ ๋ฐ์ํ ๊ณํ์ด๋ค.
๋ง์น๋ฉฐ
์ด๋ฒ ํ๋ก์ ํธ๋ฅผ ํตํด ๊ฐ์ฅ ํฌ๊ฒ ๋๋ ๊ฒ์ ๊ธฐ๋ฅ ๊ตฌํ ์์ฒด๋ณด๋ค ์ ์ง๋ณด์์ฑ๊ณผ ํ์ฅ์ฑ์ ๊ณ ๋ คํ ์ค๊ณ์ ์ค์์ฑ์ด์๋ค. 3์ฃผ ๋์ ์๋ง์ ๊ณ ๋ฏผ๊ณผ ์ฝ์ง ์๋ ์ฝ์ง์ ํ๋ฉฐ, ๋จ์ํ ์๋ํ๋ ์ฝ๋๊ฐ ์๋๋ผ '์ ์ค๊ณ๋ ์ฝ๋'๋ฅผ ๋ง๋๋ ๊ฒ์ด ์ผ๋ง๋ ์ค์ํ์ง ๊นจ๋ซ๊ฒ ๋์๋ค. ๋ํ, ์๋ก์ด ๊ธฐ์ ์ ์ต๋ํ๊ณ ์ด๋ฅผ ์ ์ฉํ๋ ๊ณผ์ ์์ ๋ง์ ์ฑ์ฅ์ ์ด๋ฃจ์๋ค.
์์ง ํญํด์ ๋ฐ์ด ๋จ์์ง๋ง ์กฐ๊ธ์ฉ ์ฑ์ฅํ๊ณ ์์์ ๋๋ผ๊ณ ์๊ณ , ํ๋ค์ง๋ง ๋์์ ๋ฟ๋ฏํจ๋ ํฌ๋ค. ์์ผ๋ก ๋จ์ ๊ธฐ๊ฐ ๋์๋ ๊ณ์ํด์ ๋ฐฐ์ฐ๊ณ , ์ด ํ๋ก์ ํธ๋ฅผ ๋ ๊ฐ์ ํ๊ธฐ ์ํด ๋
ธ๋ ฅํ ๊ฒ์ด๋ค. ์ด ๊ณผ์ ์ด ๋๋ ๋์ฏค์๋ ์ง๊ธ๋ณด๋ค ํจ์ฌ ๋ ๋์์ง ๋ชจ์ต์ ๊ธฐ๋ํ๋ฉฐ, ๋๊น์ง ์ต์ ์ ๋คํด๋ณด๋ ค๊ณ ํ๋ค.