Skip to content

[1장_이동훈] Pull Request #2

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

Merged
merged 7 commits into from
Mar 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/main/kotlin/hoondong/Audience.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package hoondong

class Audience(private val bag: Bag) {
fun buy(ticket: Ticket): Long {
return bag.hold(ticket)
}
}
34 changes: 34 additions & 0 deletions src/main/kotlin/hoondong/Bag.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package hoondong

class Bag(private var invitation: Invitation? = null) {
var amount: Long = 0L
private set
private var ticket: Ticket? = null

private fun hasInvitation() = invitation != null

fun hasTicket() = ticket != null

private fun setTicket(ticket: Ticket) {
this.ticket = ticket
}

private fun minusAmount(amount: Long) {
this.amount -= amount
}

fun plusAmount(amount: Long) {
this.amount += amount
}

fun hold(ticket: Ticket): Long {
return if (hasInvitation()) {
setTicket(ticket)
0L
} else {
minusAmount(ticket.fee)
setTicket(ticket)
ticket.fee
}
}
}
7 changes: 7 additions & 0 deletions src/main/kotlin/hoondong/Invitation.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package hoondong

import java.time.LocalDateTime

class Invitation(private val whenDate: LocalDateTime) {
// `when` 은 코틀린 키워드이므로 이름 변경
}
46 changes: 46 additions & 0 deletions src/main/kotlin/hoondong/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# 1장 객체, 설계

## 소프트웨어 설계 이론

실무가 어느정도 발전하고 난 다음에야 실용성을 입증하는 이론이 만들어진다.

소프트웨어 설계에 대한 이론은 비교적 최근에 나타났다.

유지보수에 대한 이론은 더더욱 발표가 되지 않고 있다.

결국 이론보다 실무에 초점을 맞추어야 효과적이다.

## 이해하기 어려운 코드

우리의 상식에서 벗어난 동작을 하는 코드

객체 사이의 의존성이 높아 변경에 취약한 코드

## 객체지향의 이점

캡슐화를 이용해 의존성을 적절히 관리함으로써 객체 사이의 결합도를 낮추는 것

데이터와 프로세스가 동일한 모듈에 위치하기에 이해하기 쉬움

객체 내부의 변경이 외부에 파급되지 않도록 하여 변경에 용이함

## 의인화

현실 세계에서는 수동적인 존재이더라도 객체지향의 관점에서는 능동적인 존재로 설계하는 것

객체지향에서는 각 객체가 책임져야 할 데이터와 프로세스는 각자 가져야함

## 좋은 설계란?

오늘 요구하는 기능을 온전히 수행하면서 내일의 변경을 매끄럽게 수용할 수 있는 것

- 요구사항이 항상 변경되기 때문
- 코드를 변경할 때 버그가 추가될 가능성이 높기 때문

⇒ 변경에 유연하게 대응할 수 있는 코드

## 의존성을 낮추기만 하면 좋은 코드일까?

의존성을 낮추게 된다면, 각 객체가 갖는 자율성이 떨어진다.

결국 결합도와 자율성은 트레이드오프이기 때문에 적절히 설계하는 것이 중요하다.
7 changes: 7 additions & 0 deletions src/main/kotlin/hoondong/Theater.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package hoondong

class Theater(private val ticketSeller: TicketSeller) {
fun enter(audience: Audience) {
ticketSeller.sellTo(audience)
}
}
3 changes: 3 additions & 0 deletions src/main/kotlin/hoondong/Ticket.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package hoondong

class Ticket(val fee: Long = 0L)
25 changes: 25 additions & 0 deletions src/main/kotlin/hoondong/TicketOffice.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package hoondong

class TicketOffice(private var amount: Long, vararg tickets: Ticket) {
private val tickets: MutableList<Ticket> = mutableListOf()

init {
this.tickets.addAll(tickets)
}

private fun getTicket() = tickets.removeAt(0)

fun minusAmount(amount: Long) {
this.amount -= amount
}

private fun plusAmount(amount: Long) {
this.amount += amount
}

fun sellTicketTo(audience: Audience) {
val ticket: Ticket = getTicket()
val fee = audience.buy(ticket)
plusAmount(fee)
}
}
7 changes: 7 additions & 0 deletions src/main/kotlin/hoondong/TicketSeller.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package hoondong

class TicketSeller(private val ticketOffice: TicketOffice) {
fun sellTo(audience: Audience) {
ticketOffice.sellTicketTo(audience)
}
}
49 changes: 49 additions & 0 deletions src/test/kotlin/hoondong/TheaterTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package hoondong

import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import java.time.LocalDateTime
import kotlin.test.assertEquals

@DisplayName("소극장 테스트코드")
class TheaterTest {
private lateinit var theater: Theater
private lateinit var ticketSeller: TicketSeller
private lateinit var ticketOffice: TicketOffice
private lateinit var tickets: MutableList<Ticket>

@BeforeEach
fun init() {
tickets = mutableListOf()
(0..4).forEach { tickets.add(Ticket(1)) }
ticketOffice = TicketOffice(5, *(tickets.toTypedArray()))
ticketSeller = TicketSeller(ticketOffice)
theater = Theater(ticketSeller)
}

@Test
@DisplayName("초대장이 있는 경우 판매원이 티켓을 관객에게 전달한다.")
fun hasNoInvitation() {
val bag = Bag(Invitation(LocalDateTime.now()))
bag.plusAmount(10)
val audience = Audience(bag)
theater.enter(audience)

assertEquals(bag.hasTicket(), true)
assertEquals(10, bag.amount)
}

@Test
@DisplayName("초대장이 없는 경우 관객이 요금을 지불하고 티켓을 받는다.")
fun hasInvitation() {
val bag = Bag().also {
it.plusAmount(10)
}
val audience = Audience(bag)
theater.enter(audience)

assertEquals(bag.hasTicket(), true)
assertEquals(9, bag.amount)
}
}