Skip to content
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

[둘리] 1, 2단계 영화 티켓 예매 제출합니다. #7

Merged
merged 71 commits into from
Apr 19, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
81ab027
docs: 클래스와 액티비티 설계도 작성
whk06061 Apr 11, 2023
545de51
feat: Movie 데이터 클래스 작성
whk06061 Apr 11, 2023
766d546
docs: 설계도 수정
whk06061 Apr 11, 2023
4c79b1a
feat: Price 클래스 구현
whk06061 Apr 11, 2023
4396e2c
feat: TicketingInfo 클래스 구현
whk06061 Apr 11, 2023
282882b
refactor: TicketingInfo name->title로 수정
whk06061 Apr 11, 2023
4690eae
feat: ListView, ListAdapter 구현
whk06061 Apr 11, 2023
2bc5a77
feat: 문자열 상수 @string으로 분할
whk06061 Apr 11, 2023
15cf193
feat: MovieListActivity 구현
whk06061 Apr 11, 2023
c75d5a7
feat: activity_ticketing xml 구현
whk06061 Apr 11, 2023
e38faa0
refactor: xml 더미데이터 삭제
whk06061 Apr 11, 2023
2616c9a
refactor: Price 클래스 value class 로 변경
whk06061 Apr 11, 2023
7c5e91f
feat: TicketingActivity 구현
whk06061 Apr 11, 2023
761850e
feat: activity_movie_ticket xml 구현
whk06061 Apr 11, 2023
013a294
feat: MovieTicketActivity 구현
whk06061 Apr 11, 2023
adf25b7
refactor: activity_movie_ticket.xml 글자 볼드 처리 수정
whk06061 Apr 11, 2023
f50a2ce
refactor: ViewHolder 적용
whk06061 Apr 11, 2023
48a66c5
refactor: 불필요한 MainActivity 삭제
whk06061 Apr 11, 2023
47f12c8
refactor: 상영일, 러닝타임 문자 출력 수정
whk06061 Apr 11, 2023
443e903
refactor: activity_ticketing.xml 본문 스크롤 되도록 수정
whk06061 Apr 12, 2023
e7db664
docs: 클래스 설계도 수정
whk06061 Apr 12, 2023
aa74fa9
feat: PlayingTimes 구현
whk06061 Apr 12, 2023
c05ff0e
refactor: PlayintDate, PlayingTime 따로 받도록 수정
whk06061 Apr 12, 2023
fc093c7
refactor: 직렬화되도록 수정
whk06061 Apr 12, 2023
3f5cc8f
feat: 날짜 시간 선택 spinner 구현
whk06061 Apr 12, 2023
b512714
feat: 할인 정책 구현
whk06061 Apr 12, 2023
6d2199c
feat: 화면 회전 시 데이터 유지 구현
whk06061 Apr 12, 2023
520d74b
refactor: 영화 더미 데이터 가져오는 함수 분리
whk06061 Apr 13, 2023
3ddf00b
refactor: 로직 함수로 분리
whk06061 Apr 13, 2023
fe47ef3
feat: Formatter 구현
whk06061 Apr 13, 2023
5525f7b
feat: Intent getSerializable 확장함수 구현
whk06061 Apr 13, 2023
7dce42c
refactor: MovieListAdapter, MovieTicketActivity 리팩터링
whk06061 Apr 13, 2023
70e7f6b
test: FormatterTest 구현
whk06061 Apr 13, 2023
6b3843c
refactor: TicketingActivity.kt 코드 리팩토링
whk06061 Apr 13, 2023
c881fba
refactor: 패키지 구조 분리 및 액티비티 명 수정
whk06061 Apr 13, 2023
4d17d10
refactor: SpinnerListener, Keys 분리
hyemdooly Apr 14, 2023
10f416c
refactor: DummyData 분리
hyemdooly Apr 14, 2023
303b877
refactor: getString 필요없는 format 함수 사용 삭제
hyemdooly Apr 14, 2023
ed85463
refactor: require 수정
hyemdooly Apr 14, 2023
452126c
refactor: ViewHolder 필드들 nullable인 것 수정
hyemdooly Apr 14, 2023
77afa95
refactor: PlayingTimes 리팩터링
hyemdooly Apr 14, 2023
54b5c30
fix: Exception 발생 버그 수정
hyemdooly Apr 14, 2023
8609c35
refactor: Policies 따로 분할, 범용적으로 사용할 수 있도록 수정
hyemdooly Apr 14, 2023
2e67294
test: DiscountPolicy 클래스 변경으로 인한 테스트 수정 및 추가
hyemdooly Apr 14, 2023
187af84
refactor: Formatter 삭제
hyemdooly Apr 14, 2023
6fc6324
refactor: 모든 layout Linear에서 Constraint로 변경
hyemdooly Apr 14, 2023
a5e2e98
refactor: ktlintFormat 적용
hyemdooly Apr 14, 2023
37cf719
refactor: FormatterTest 삭제
hyemdooly Apr 14, 2023
b8c06a2
refactor: null일시 토스트 띄운 후 뒤로가도록 수정
hyemdooly Apr 15, 2023
e2c4c55
refactor: 확장함수명 변경
hyemdooly Apr 15, 2023
0fe291d
refactor: 패키지 변경 및 뷰 값 세팅 클래스 분리
hyemdooly Apr 15, 2023
dc6ad79
refactor: 패키지 변경
hyemdooly Apr 15, 2023
e062f6f
refactor: MovieDetailActivity, TicketResultActivity 함수 분리
hyemdooly Apr 15, 2023
9864e56
refactor: DummyData 추가, 변수명 변경
hyemdooly Apr 15, 2023
5cca9a1
refactor: MovieDTO 추가
hyemdooly Apr 15, 2023
a45c442
refactor: Key들 위치 변경, Keys object 삭제
hyemdooly Apr 16, 2023
9f8e452
refactor: 확장함수명 변경
hyemdooly Apr 16, 2023
d04bd6c
refactor: else문 삭제
hyemdooly Apr 16, 2023
5336de6
refactor: scope function run 대신 with 사용
hyemdooly Apr 17, 2023
77cd778
refactor: package 이동, MovieDTO 및 Mapper 수정
hyemdooly Apr 17, 2023
1c36e77
refactor: view를 객체 내부에서 찾도록 변경
hyemdooly Apr 17, 2023
186d6f6
refactor: key가 없으면 빈 리스트를 반환하는 Map 확장함수 구현
hyemdooly Apr 17, 2023
b1bffce
refactor: 모듈 분리
hyemdooly Apr 18, 2023
b13a913
refactor: ViewHolders Map 생성, set 함수 이동
hyemdooly Apr 18, 2023
f8c3245
refactor: MovieListItemListener 생성 후 Listener 분할
hyemdooly Apr 18, 2023
ae36175
refactor: getKeyFromIndex Map 확장함수 생성
hyemdooly Apr 18, 2023
f2bfce9
refactor: MovieDTO -> MovieModel 네이밍 변경
hyemdooly Apr 18, 2023
1dc76f1
refactor: View Setting 함수 하나로 합치기
hyemdooly Apr 18, 2023
ac7b7e6
refactor: SpinnerAdapter 함수 분리
hyemdooly Apr 18, 2023
39215c6
refactor: TicketingInfo -> Ticket으로 변경, payment 삭제
hyemdooly Apr 18, 2023
b89051c
refactor: TicketModel 생성, 도메인 객체 의존성 제거
hyemdooly Apr 18, 2023
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
Prev Previous commit
Next Next commit
refactor: MovieDTO 추가
  • Loading branch information
hyemdooly committed Apr 15, 2023
commit 5cca9a14f82383aba7cffcb83cf4f814a2bcee4d
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,27 @@ import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import woowacourse.movie.R
import woowacourse.movie.model.Movie
import woowacourse.movie.model.MovieDTO
import woowacourse.movie.util.Keys
import woowacourse.movie.util.getVersionDependentSerializableExtra

class MovieDetailActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_movie_detail)
val movie: Movie? = intent.getVersionDependentSerializableExtra(Keys.MOVIE_KEY)
if (movie != null) {
initMovieDetailView(movie)
initReservationInfoView(savedInstanceState, movie)
val movieDTO: MovieDTO? = intent.getVersionDependentSerializableExtra(Keys.MOVIE_KEY)
if (movieDTO != null) {
initMovieDetailView(movieDTO)
initReservationInfoView(savedInstanceState, movieDTO)
} else {
Toast.makeText(this, DATA_LOADING_ERROR_MESSAGE, Toast.LENGTH_LONG).show()
finish()
}
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}

private fun initMovieDetailView(movie: Movie) {
MovieDetailViewInitializer(movie).run {
private fun initMovieDetailView(movieDTO: MovieDTO) {
MovieDetailViewInitializer(movieDTO).run {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

run 스코프 함수를 선택한 이유가 무엇인가요?
다른 스코프 함수들과 어떻게 다를까요?

Copy link
Author

@hyemdooly hyemdooly Apr 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scope function를 살펴보면 두 가지 기준으로 차이점이 나뉩니다.

  1. 객체 reference를 호출하는 방법이 it인가, this인가 : it - let, also | this - run, with, apply
  2. 반환값이 Lambda의 결과인가, 객체 reference인가 : Lambda result - let, run, with | 객체 reference - apply, also

사실 run을 선택한 이유는 뜻 그대로 실행한다는 의미로 사용했는데요..!
위 기준에서 서로 겹치는 run과 with에 대해 좀 더 살펴보았습니다.
run과 with의 가장 큰 차이점은 (지금 코드에서 사용한 run의 경우) run은 확장함수이나 with는 아니라는 점, 그리고 run은 nullable 변수에서 사용 가능하나 with에서는 그렇지 않다는 점입니다.
with는 "이미 생성된" 객체에 대해 코드 중복을 줄이고 싶을 때, run은 객체 생성 후 "객체 저장 없이" 원하는 값만 받아오고 싶을 때도 사용할 수 있습니다.
따라서, 현재 코드에서는 객체가 nullable이 아니며, return값이 필요 없고 한 객체에 대해 여러 함수를 사용하려고 하고 있기 때문에 의미적으로 with가 보기 좋아보입니다!

Copy link

@malibinYun malibinYun Apr 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋은 공부가 되었기를 바라요 :)

조금 추가하면,
with는 사실 나머지 4개와는 다르게 확장함수가 아니랍니다.
그래서 run과의 비교군으로는 잘 맞지 않아요.

사실 run을 선택한 이유는 뜻 그대로 실행한다는 의미로 사용했는데요..!

저도 공감해요.
다만, run의 반환 값은 Lambda의 결과 라는 것이에요.
그렇기에 이 반환 값을 사용하지 않으므로, 적절하지 않다고 생각해요.

저는 이런 경우, 수신 객체를 가지고 또 무언가를 수행하니, also를 주로 활용해요.
확장 함수의 결과가 변환되지도 않기에 활용해요.

확장 함수에 대한 비교로 말씀 드렸는데, 둘리 의견 처럼 with가 더 적절해 보이네요 :)

제 의견은 정답이 아니니, 이런 의견도 있다 정도로 생각해주시면 좋겠어요 😊


다만, 이러한 일들이 정말 스코프 함수가 필요했는 지 더 고민해보면 좋겠어요.
정말 외부에서 일일이 MovieDetailViewInitializer 객체의 메서드를 호출해주어야할까요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

일일히 호출하기 보다 생성자에서 Movie 데이터를 받아서 한번에 처리할 수 있을 것 같습니다. :)

그리고 한 가지 더 질문드리고 싶은 부분이 있습니다!

inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    return receiver.block()
}

with를 찾아볼 때 블로그에 반환값이 없다라는 말을 자주 봤는데요!
with의 정의를 보면 반환 타입이 block의 결과인데... 반환은 있는게 맞지만, 이 반환값을 어딘가에 저장해서 사용하지는 않는다는 의미인건가요?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with의 정의를 보면 반환 타입이 block의 결과인데...

정확히 짚으셨네요!
저는 사실 한글로 된 블로그에 그리 신뢰도가 높지 않아요.
생각보다 다른 블로그의 글을 그대로 옮겨다가 적는 경우가 꽤 많아요.
그렇기에 잘못된 정보도 그대로 옮기는 경우를 많이 보았어요.

저는 둘리가 건강한 검색을 하고 있다고 생각해요.
믿을 건 영어 공식 문서와 실제 코드입니다 🙂

initImageView(findViewById(R.id.img_movie))
initTitle(findViewById(R.id.text_title))
initPlayingDate(findViewById(R.id.text_playing_date))
Expand All @@ -36,12 +36,12 @@ class MovieDetailActivity : AppCompatActivity() {
}
}

private fun initReservationInfoView(savedInstanceState: Bundle?, movie: Movie) {
private fun initReservationInfoView(savedInstanceState: Bundle?, movieDTO: MovieDTO) {
val savedCount = savedInstanceState?.getInt(Keys.COUNT_KEY) ?: DEFAULT_COUNT
val savedDate = savedInstanceState?.getInt(Keys.SPINNER_DATE_KEY) ?: DEFAULT_POSITION
val savedTime = savedInstanceState?.getInt(Keys.SPINNER_TIME_KEY) ?: DEFAULT_POSITION

ReservationInfoViewInitializer(movie).run {
ReservationInfoViewInitializer(movieDTO).run {
initCount(savedCount, findViewById(R.id.text_count))
initMinusButton(findViewById(R.id.btn_minus), findViewById(R.id.text_count))
initPlusButton(findViewById(R.id.btn_plus), findViewById(R.id.text_count))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,32 @@ package woowacourse.movie.activity.moviedetail
import android.widget.ImageView
import android.widget.TextView
import woowacourse.movie.R
import woowacourse.movie.model.Movie
import woowacourse.movie.model.MovieDTO
import java.time.format.DateTimeFormatter

class MovieDetailViewInitializer(private val movie: Movie) {
class MovieDetailViewInitializer(private val movieDTO: MovieDTO) {

fun initDescription(textView: TextView) {
textView.text = movie.description
textView.text = movieDTO.description
}

fun initRunningTime(textView: TextView) {
textView.text = textView.context.getString(R.string.running_time, movie.runningTime)
textView.text = textView.context.getString(R.string.running_time, movieDTO.runningTime)
}

fun initPlayingDate(textView: TextView) {
textView.text = textView.context.getString(
R.string.playing_time,
DateTimeFormatter.ofPattern(textView.context.getString(R.string.date_format)).format(movie.playingTimes.startDate),
DateTimeFormatter.ofPattern(textView.context.getString(R.string.date_format)).format(movie.playingTimes.endDate)
DateTimeFormatter.ofPattern(textView.context.getString(R.string.date_format)).format(movieDTO.playingTimes.startDate),
DateTimeFormatter.ofPattern(textView.context.getString(R.string.date_format)).format(movieDTO.playingTimes.endDate)
)
}

fun initTitle(textView: TextView) {
textView.text = movie.title
textView.text = movieDTO.title
}

fun initImageView(imageView: ImageView) {
imageView.setImageResource(movie.image)
imageView.setImageResource(movieDTO.image)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@ import android.widget.Button
import android.widget.Spinner
import android.widget.TextView
import woowacourse.movie.activity.ticketresult.TicketResultActivity
import woowacourse.movie.model.Movie
import woowacourse.movie.model.MovieDTO
import woowacourse.movie.model.Price
import woowacourse.movie.model.TicketingInfo
import woowacourse.movie.util.DiscountPolicies
import woowacourse.movie.util.Keys
import java.time.LocalDate
import java.time.LocalTime

class ReservationInfoViewInitializer(private val movie: Movie) {
class ReservationInfoViewInitializer(private val movieDTO: MovieDTO) {
fun initReserveButton(reserveButton: Button, countView: TextView, dateSpinner: Spinner, timeSpinner: Spinner) {
reserveButton.setOnClickListener {
val intent = Intent(it.context, TicketResultActivity::class.java)
val ticketingInfo = TicketingInfo.of(
DiscountPolicies.policies,
movie.title,
movieDTO.title,
dateSpinner.selectedItem as LocalDate,
timeSpinner.selectedItem as LocalTime,
countView.text.toString().toInt(),
Expand All @@ -33,7 +33,7 @@ class ReservationInfoViewInitializer(private val movie: Movie) {
}

fun initTimeSpinner(savedTimePosition: Int, dateSpinner: Spinner, timeSpinner: Spinner) {
val times = movie.playingTimes.times[dateSpinner.selectedItem] ?: emptyList()
val times = movieDTO.playingTimes.times[dateSpinner.selectedItem] ?: emptyList()
timeSpinner.adapter =
ArrayAdapter(timeSpinner.context, android.R.layout.simple_spinner_item, times).apply {
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
Expand All @@ -42,13 +42,13 @@ class ReservationInfoViewInitializer(private val movie: Movie) {
}

fun initDateSpinner(savedDatePosition: Int, dateSpinner: Spinner, timeSpinner: Spinner) {
val dates = movie.playingTimes.times.keys.sorted()
val dates = movieDTO.playingTimes.times.keys.sorted()
dateSpinner.adapter =
ArrayAdapter(dateSpinner.context, android.R.layout.simple_spinner_item, dates).apply {
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
}
dateSpinner.setSelection(savedDatePosition, false)
dateSpinner.onItemSelectedListener = DateSpinnerListener(movie.playingTimes, dates, timeSpinner)
dateSpinner.onItemSelectedListener = DateSpinnerListener(movieDTO.playingTimes, dates, timeSpinner)
}

fun initMinusButton(minusButton: Button, countView: TextView) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class MovieListActivity : AppCompatActivity() {
setContentView(R.layout.activity_movie_list)

val listView = findViewById<ListView>(R.id.list_view)
val adapter = MovieListAdapter(DummyData.movies)
val adapter = MovieListAdapter(DummyData.movieDTOS)
listView.adapter = adapter
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ import android.widget.ImageView
import android.widget.TextView
import woowacourse.movie.R
import woowacourse.movie.activity.moviedetail.MovieDetailActivity
import woowacourse.movie.model.Movie
import woowacourse.movie.model.MovieDTO
import woowacourse.movie.util.Keys
import java.time.format.DateTimeFormatter

class MovieListAdapter(private val movies: List<Movie>) : BaseAdapter() {
class MovieListAdapter(private val movieDTOS: List<MovieDTO>) : BaseAdapter() {
override fun getCount(): Int {
return movies.size
return movieDTOS.size
}

override fun getItem(position: Int): Any {
return movies[position]
return movieDTOS[position]
}

override fun getItemId(position: Int): Long {
Expand All @@ -34,10 +34,10 @@ class MovieListAdapter(private val movies: List<Movie>) : BaseAdapter() {
if (convertView == null) view.tag = getViewHolder(view)

val holder = view.tag as ViewHolder
val movie = getItem(position) as Movie
setViewHolder(holder, movie, parent?.context) {
val movieDTO = getItem(position) as MovieDTO
setViewHolder(holder, movieDTO, parent?.context) {
val intent = Intent(view.context, MovieDetailActivity::class.java)
intent.putExtra(Keys.MOVIE_KEY, movie)
intent.putExtra(Keys.MOVIE_KEY, movieDTO)
view.context.startActivity(intent)
}
return view
Expand All @@ -51,15 +51,15 @@ class MovieListAdapter(private val movies: List<Movie>) : BaseAdapter() {
view.findViewById(R.id.btn_reserve)
)

private fun setViewHolder(holder: ViewHolder, movie: Movie, context: Context?, clickListener: OnClickListener) {
holder.image.setImageResource(movie.image)
holder.title.text = movie.title
private fun setViewHolder(holder: ViewHolder, movieDTO: MovieDTO, context: Context?, clickListener: OnClickListener) {
holder.image.setImageResource(movieDTO.image)
holder.title.text = movieDTO.title
holder.playingDate.text = context?.getString(
R.string.playing_time,
DateTimeFormatter.ofPattern(context.getString(R.string.date_format)).format(movie.playingTimes.startDate),
DateTimeFormatter.ofPattern(context.getString(R.string.date_format)).format(movie.playingTimes.endDate)
DateTimeFormatter.ofPattern(context.getString(R.string.date_format)).format(movieDTO.playingTimes.startDate),
DateTimeFormatter.ofPattern(context.getString(R.string.date_format)).format(movieDTO.playingTimes.endDate)
)
holder.runningTime.text = context?.getString(R.string.running_time, movie.runningTime)
holder.runningTime.text = context?.getString(R.string.running_time, movieDTO.runningTime)
holder.reserveButton.setOnClickListener(clickListener)
}

Expand Down
3 changes: 1 addition & 2 deletions app/src/main/java/woowacourse/movie/model/Movie.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package woowacourse.movie.model

data class Movie(
val image: Int,
val title: String,
val playingTimes: PlayingTimes,
val runningTime: Int,
val description: String
) : java.io.Serializable
)
11 changes: 11 additions & 0 deletions app/src/main/java/woowacourse/movie/model/MovieDTO.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package woowacourse.movie.model

import androidx.annotation.DrawableRes

data class MovieDTO(
@DrawableRes val image: Int,
val title: String,
val playingTimes: PlayingTimes,
val runningTime: Int,
val description: String
) : java.io.Serializable

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

도메인과 뷰에서 관리할 모델을 분리하셨네요 👍
Movie 객체에서 Serializable 제거도 잘 해주셨네요 :)

다만 DTO는 안드로이드에서 사용하지 않는 용어입니다. spring 진영에서 자주 사용하는 용어예요.
구글 문서 등을 잘 참고해서 다른 종류의 이름을 붙여보세요 :)
이름 짓기는 세상 어려운 일이니 충분히 고민해보세요.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Model이라는 단어를 사용하여 수정했습니다!
Entity나 ViewModel이라는 네이밍을 사용하는 것 같은데, Entity는 데이터베이스에서 주로 사용되는 용어로 가장 하위 단계인 것 같고 ViewModel이 뷰에 대한 모델이라는 의미에 가까운 네이밍인 것 같습니다.
MovieViewModel은 너무 긴 것 같아 MovieModel로 수정했습니다.

22 changes: 11 additions & 11 deletions app/src/main/java/woowacourse/movie/util/DummyData.kt
Original file line number Diff line number Diff line change
@@ -1,69 +1,69 @@
package woowacourse.movie.util

import woowacourse.movie.R
import woowacourse.movie.model.Movie
import woowacourse.movie.model.MovieDTO
import woowacourse.movie.model.PlayingTimes
import java.time.LocalDate

object DummyData {
val movies = listOf(
Movie(
val movieDTOS = listOf(
MovieDTO(
R.drawable.img,
"해리포터와 마법사의 돌",
PlayingTimes(LocalDate.of(2023, 3, 1), LocalDate.of(2023, 3, 31)),
152,
"《해리 포터와 마법사의 돌》은 2001년 J. K. 롤링의 동명 소설을 원작으로 하여 만든, 영국과 미국 합작, 판타지 영화이다. 해리포터 시리즈 영화 8부작 중 첫 번째에 해당하는 작품이다. 크리스 콜럼버스가 감독을 맡았다."
),
Movie(
MovieDTO(
R.drawable.img,
"해리포터와 마법사의 돌",
PlayingTimes(LocalDate.of(2023, 3, 1), LocalDate.of(2023, 3, 31)),
152,
"《해리 포터와 마법사의 돌》은 2001년 J. K. 롤링의 동명 소설을 원작으로 하여 만든, 영국과 미국 합작, 판타지 영화이다. 해리포터 시리즈 영화 8부작 중 첫 번째에 해당하는 작품이다. 크리스 콜럼버스가 감독을 맡았다."
),
Movie(
MovieDTO(
R.drawable.img,
"해리포터와 마법사의 돌",
PlayingTimes(LocalDate.of(2023, 3, 1), LocalDate.of(2023, 3, 31)),
152,
"《해리 포터와 마법사의 돌》은 2001년 J. K. 롤링의 동명 소설을 원작으로 하여 만든, 영국과 미국 합작, 판타지 영화이다. 해리포터 시리즈 영화 8부작 중 첫 번째에 해당하는 작품이다. 크리스 콜럼버스가 감독을 맡았다."
),
Movie(
MovieDTO(
R.drawable.img,
"해리포터와 마법사의 돌",
PlayingTimes(LocalDate.of(2023, 3, 1), LocalDate.of(2023, 3, 31)),
152,
"《해리 포터와 마법사의 돌》은 2001년 J. K. 롤링의 동명 소설을 원작으로 하여 만든, 영국과 미국 합작, 판타지 영화이다. 해리포터 시리즈 영화 8부작 중 첫 번째에 해당하는 작품이다. 크리스 콜럼버스가 감독을 맡았다."
),
Movie(
MovieDTO(
R.drawable.img,
"해리포터와 마법사의 돌",
PlayingTimes(LocalDate.of(2023, 3, 1), LocalDate.of(2023, 3, 31)),
152,
"《해리 포터와 마법사의 돌》은 2001년 J. K. 롤링의 동명 소설을 원작으로 하여 만든, 영국과 미국 합작, 판타지 영화이다. 해리포터 시리즈 영화 8부작 중 첫 번째에 해당하는 작품이다. 크리스 콜럼버스가 감독을 맡았다."
),
Movie(
MovieDTO(
R.drawable.img,
"해리포터와 마법사의 돌",
PlayingTimes(LocalDate.of(2023, 3, 1), LocalDate.of(2023, 3, 31)),
152,
"《해리 포터와 마법사의 돌》은 2001년 J. K. 롤링의 동명 소설을 원작으로 하여 만든, 영국과 미국 합작, 판타지 영화이다. 해리포터 시리즈 영화 8부작 중 첫 번째에 해당하는 작품이다. 크리스 콜럼버스가 감독을 맡았다."
),
Movie(
MovieDTO(
R.drawable.img,
"해리포터와 마법사의 돌",
PlayingTimes(LocalDate.of(2023, 3, 1), LocalDate.of(2023, 3, 31)),
152,
"《해리 포터와 마법사의 돌》은 2001년 J. K. 롤링의 동명 소설을 원작으로 하여 만든, 영국과 미국 합작, 판타지 영화이다. 해리포터 시리즈 영화 8부작 중 첫 번째에 해당하는 작품이다. 크리스 콜럼버스가 감독을 맡았다."
),
Movie(
MovieDTO(
R.drawable.img,
"해리포터와 마법사의 돌",
PlayingTimes(LocalDate.of(2023, 3, 1), LocalDate.of(2023, 3, 31)),
152,
"《해리 포터와 마법사의 돌》은 2001년 J. K. 롤링의 동명 소설을 원작으로 하여 만든, 영국과 미국 합작, 판타지 영화이다. 해리포터 시리즈 영화 8부작 중 첫 번째에 해당하는 작품이다. 크리스 콜럼버스가 감독을 맡았다."
),
Movie(
MovieDTO(
R.drawable.img,
"해리포터와 마법사의 돌",
PlayingTimes(LocalDate.of(2023, 3, 1), LocalDate.of(2023, 3, 31)),
Expand Down
13 changes: 13 additions & 0 deletions app/src/main/java/woowacourse/movie/util/Mapper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package woowacourse.movie.util

import androidx.annotation.DrawableRes
import woowacourse.movie.model.Movie
import woowacourse.movie.model.MovieDTO

fun MovieDTO.toDomain(): Movie {
return Movie(title, playingTimes, runningTime, description)
}

fun Movie.toPresentation(@DrawableRes res: Int): MovieDTO {
return MovieDTO(res, title, playingTimes, runningTime, description)
}