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

Week6 필수,심화 과제 #10

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
Empty file.
4 changes: 2 additions & 2 deletions app/src/main/java/org/sopt/and/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package org.sopt.and
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import org.sopt.and.navigation.Navigation
import org.sopt.and.services.AppContext
import org.sopt.and.data.service.AppContext
import org.sopt.and.presentation.navigation.Navigation
import org.sopt.and.ui.theme.ANDANDROIDTheme

class MainActivity : ComponentActivity() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.sopt.and.data.datasource

import org.sopt.and.data.model.response.GetMyHobbyResponseDto
import org.sopt.and.data.service.UserService

class GetMyHobbyDataSource(
private val userService: UserService
) {
suspend fun getMyHobby(): GetMyHobbyResponseDto = userService.getMyHobby()

Choose a reason for hiding this comment

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

아키텍처를 적용해보는 것도 좋긴 한데요. 개인적으로 우려가 됩니다.

첫 주차에 봤던 재민 님의 코드가 저는 더 좋은 코드인 것처럼 느껴집니다. 재민님의 의도가 더 잘 보이는 코드 같아요.
지금은 조금 이해하기 어려운 코드가 된 것 같습니다.

이런 구조는 유지보수성을 높이기 보다 경직성을 높인다고 보입니다.

get /user/my-hobby 라는 api 하나를 화면에서 호출하기 위해서 너무나 너무나 너무나도 많은 단계가 필요해요.

api 명세는 UserService 에 정의하구요.
이를 호출해주는 DataSource는 GetMyHobbyDataSource 클래스에 정의합니다.
이 DataSource는 GetMyHobbyRepository 인터페이스의 실제 구현체인 GetMyHobbyRepositoryImpl 을 생성하기 위해서 넘겨집니다.
이렇게 만든 Repository를 GetMyHobbyUseCase 생성자에 넣어주고요.
최종적으로 ViewModel은 GetMyHobbyUseCase 인스턴스를 주입받아서 사용합니다.

여기에 등장한 객체만 UserService, GetMyHobbyDataSource, GetMyHobbyRepositoryImpl, GetMyHobbyRepository, GetMyHobbyUseCase 이렇게 총 5가지 인데요. 객체가 너무 많아보입니다.

간단한 기능 하나를 추가하는데 작성해야 하는 객체가 많다는 건 그만큼 작업할 때 공수가 많이 들어간다는 의미가 됩니다.
그렇다면 그 공수를 들여서 얻는 가치가 명확해야 합니다. 지금은 그 가치가 불명확한 상황으로 보여요.

저는 DataSource는 제외하고 Repository만 구성해보시는 걸 추천드려 볼게요.
Repository같은 경우에도 interface - implmentation 나누지 마시고 interface 없이 implementation만 구성해보시는 걸 추천드려볼게요.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

좋은 리뷰 너무 감사합니다
한번만 더 오래 고민해보겠습니다.. 저도 구현하면서 이게 맞나 라는 생각이 들었습니다
말씀하신 어떤 가치가 있을 수 있는지를 생각해보겠습니다

Copy link
Contributor

Choose a reason for hiding this comment

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

안녕하세요. 안드로이드 파트장 배지현입니다.
먼저, 바쁘실텐데도 불구하고 매주 정성스러운 리뷰 남겨주셔서 감사합니다.

저도 단순히 아키텍처를 도입한 코드가 좋은 코드가 아니며 팀 상황이나 프로젝트 볼륨에 맞춰 아키텍처 도입을 결정하고 이를 바탕으로 구현된 코드가 의미가 있다고 생각해요.
그렇기 때문에 세미나 때 아키텍처를 다루고 이에 대한 과제를 내면서 그냥 단순히 아키텍처적인 지식을 전달하기보다는 아키텍처의 필요성이과 각 객체의 책임을 이해시키려고 노력을 많이 했던 것 같아요.
특히, 과제에서는 '단순히 아키텍처를 적용하라'에서 끝이 아니라 어떤 아키텍처를 고르고, 왜 골랐는지, 그리고 각 구성요소들의 책임을 무엇이라고 생각하고 왜 필요한지를 충분히 고민하고 코드를 작성할 수 있도록 다양한 장치들을 마련했어요.

하지만 과제의 볼륨이 아키텍처의 필요성을 느낄만한 볼륨이 아니기 때문에 아키텍처를 도입하게 되면서 '아 이 정도 수준의 볼륨에 아키텍처를 적용하는 것이 과연 옳은가? 더 많은 리소스가 드는 것이 아닌가?' 하는 생각이 드는 것이 어쩌면 당연한 일이라고 생각해요.
그럼에도 제가 이러한 과제를 낸 이유는 이러한 고민을 하는 것 자체가 파트원 친구들의 성장에 도움이 된다고 판단했기 때문이에요.
어떠한 기술을 몰라서 쓰지않는 것과 그 기술에 대해 잘 알고 있지만 프로젝트의 볼륨이나 팀 상황을 판단했을 때 사용하지 않는 것이 옳다고 생각해서 사용하지 않는 것이 다르고, 파트원 친구들이 배우고 있는 단계라는 것을 생각했을 때 세미나에서 다양한 기술을 다루고 그 기술의 필요성을 이해시키는 것, 그리고 그 기술을 실제 프로젝트에 어떻게 적용할 수 있을지를 알려주는 것이 파트원 친구들의 성장에 도움이 된다고 생각했거든요.
그래서 실제 서비스를 구현하는 것이 아닌 배움을 위한 과제이기에 실제였다면 해당 기술을 적용시키는 것이 더 비효율적일지라도 이를 해보게 하는 것 그리고 이를 통해 비효율성을 직접 느껴 아키텍처 도입에 대한 고민을 하게 하는 것이 파트원 친구들에게 더 의미가 있을 것이라 판단하여 이러한 과제를 내게 되었어요. (비효율성을 느끼지 못하더라도 아키텍처에 대한 고민을 하는 시간을 마련해주는 것 자체가 의미가 있다고 판단했습니다.)
저도 파트장이 처음이기에 그리고 아직 배우고 있는 입장이기에 이러한 방향으로 파트를 이끌어나가는 것이 맞는지, 이러한 방법이 파트원 친구들에게 정말로 도움이 될지 아직도 고민이 많네요. ㅜㅜ

승민님의 리뷰를 읽어 보니 과제가 끝난 후 discussion을 통해 과제에 대한 생각과 과제 의도를 공유하는 것보다 오히려 과제 의도를 사전에 설명하는 것이 파트원 친구들이 더 충분한 고민을 하게 만드는 것 같아요.
그리고 이러한 의도를 명예 OB 분들에게 공유드려야 더 의미있는 리뷰 시간이 될 것 같고요.
앞으로 더 나은 파트를 만들어 나갈 수 있도록 파트원 친구들이 더 많이 성장할 수 있도록 조금 더 많이 고민해보고 노력해보겠습니다.
항상 좋은 리뷰 남겨주셔서 정말 감사합니다!

Choose a reason for hiding this comment

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

1주차 재민님의 코드를 봤을 때, 코드를 고민하고 작성하신게 눈에 보였었어요.
코틀린과 안드로이드 문법은 잘 모르신다고 하셨지만 코드를 통해서 구현하고자 하는게 뭔지 의도가 잘 보이는 코드였습니다. 좋은 코드라고 생각해요.

그런데 이번에 리뷰에서는 뭔가에 쫓기는 느낌을 받았었습니다. 아직 소화되지 않은 아키텍처를 급하게 적용해보는 느낌을 지울 수 없었어요. 그리고 그렇게 코드를 작성하는 것이 좋지 않다고 믿습니다.
본인이 납득할 수 있는 수준에서 코드를 작성해야 작성하는 사람도 읽는 사람도 납득할 결과물이 나올 거라고 생각해요.

혹시 쫓기면서 작성하신 코드는 아닌지 그렇다면 너무 쫓기지 마시고 본인이 이해한 만큼 코드를 고민하고 작성하는게 좋겠다고 생각해서 리뷰를 남겼었습니다.

이 리뷰가 @jihyunniiii 님의 세미나 방향과 대치되거나 의도를 잘 못 캐치한 리뷰가 될 수 있는걸 알고 있었는데요.
엄청나게 많은 라이브러리, 아키텍쳐 등 새로운 지식을 접하는 과정에서
좋은 코드란 좋은 라이브러리, 기술, 아키텍처일 것이라고 생각하거나 이런 걸 사용해야 좋은 코드라고 생각할 수 있을 것 같아서 노파심에 리뷰를 남겨보았습니다.

}
13 changes: 13 additions & 0 deletions app/src/main/java/org/sopt/and/data/datasource/SignInDataSource.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.sopt.and.data.datasource

import org.sopt.and.data.model.request.SignInRequestDto
import org.sopt.and.data.model.response.SignInResponseDto
import org.sopt.and.data.service.UserService
import retrofit2.Response

class SignInDataSource(
private val userService: UserService
) {
suspend fun signIn(request: SignInRequestDto): Response<SignInResponseDto> =
userService.signIn(request = request)
}
13 changes: 13 additions & 0 deletions app/src/main/java/org/sopt/and/data/datasource/SignUpDataSource.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.sopt.and.data.datasource

import org.sopt.and.data.model.request.SignUpRequestDto
import org.sopt.and.data.model.response.SignUpResponseDto
import org.sopt.and.data.service.UserService
import retrofit2.Response

class SignUpDataSource(
private val userService: UserService
) {
suspend fun signUp(request: SignUpRequestDto): Response<SignUpResponseDto> =
userService.signUp(request = request)
}
47 changes: 47 additions & 0 deletions app/src/main/java/org/sopt/and/data/mapper/Mapper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.sopt.and.data.mapper

import org.sopt.and.data.model.request.SignInRequestDto
import org.sopt.and.data.model.request.SignUpRequestDto
import org.sopt.and.data.model.response.GetMyHobbyResponseResultDto
import org.sopt.and.data.model.response.SignInResponseDto
import org.sopt.and.data.model.response.SignUpResponseDto
import org.sopt.and.domain.model.MyHobbyEntity
import org.sopt.and.domain.model.SignInInformationEntity
import org.sopt.and.domain.model.SignInResponseEntity
import org.sopt.and.domain.model.SignUpInformationEntity
import org.sopt.and.domain.model.SignUpResponseEntity
import retrofit2.Response

object Mapper {
Copy link
Contributor

Choose a reason for hiding this comment

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

Mapper를 object로 관리하시는 이유가 있나요?

fun toMyHobbyEntity(getHobbyResponseResultDto: GetMyHobbyResponseResultDto) =
MyHobbyEntity(myHobby = getHobbyResponseResultDto.myHobby)

fun toSignUpResponseEntity(signUpResponseDto: Response<SignUpResponseDto>) =
signUpResponseDto.body()?.result?.let {
SignUpResponseEntity(
no = it.no,
status = signUpResponseDto.code(),
code = signUpResponseDto.body()!!.code
Copy link
Contributor

Choose a reason for hiding this comment

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

!!는 NPE를 발생시킬 수 있으니 사용을 지양합시다!

)
}

fun toSignInResponseEntity(signInResponseDto: Response<SignInResponseDto>) =
signInResponseDto.body()?.result?.let {
SignInResponseEntity(
token = it.token,
status = signInResponseDto.code(),
code = signInResponseDto.body()!!.code
)
}

fun toSignInRequestDto(signInInformationEntity: SignInInformationEntity) = SignInRequestDto(

Choose a reason for hiding this comment

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

= 이후로 줄바꿈해주시면 좋을 것 같아요!

username = signInInformationEntity.username,
password = signInInformationEntity.password
)

fun toSignUpRequestDto(signUpInformationEntity: SignUpInformationEntity) = SignUpRequestDto(

Choose a reason for hiding this comment

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

여기두 줄바꿈해서 통일해주세여

username = signUpInformationEntity.username,
password = signUpInformationEntity.password,
hobby = signUpInformationEntity.hobby
)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sopt.and.signin.dto
package org.sopt.and.data.model.request

import kotlinx.serialization.Serializable

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sopt.and.signup.dto
package org.sopt.and.data.model.request

import kotlinx.serialization.Serializable

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.sopt.and.data.model.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class GetMyHobbyResponseDto(

Choose a reason for hiding this comment

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

Dto 이름을 HTTP method를 활용해서 짓기보다는 해당 데이터 클래스가 나타내는 핵심만 딱 활용해주심 좋을 것 같아요! MyHobbyResponseDto 이런 식으루,,

val result: GetMyHobbyResponseResultDto? = null,
val code: String? = null
)

@Serializable
data class GetMyHobbyResponseResultDto(
@SerialName("hobby")
val myHobby: String
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sopt.and.signin.dto
package org.sopt.and.data.model.response

import kotlinx.serialization.Serializable

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sopt.and.signup.dto
package org.sopt.and.data.model.response

import kotlinx.serialization.Serializable

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.sopt.and.data.repositoryimpl

import org.sopt.and.data.datasource.GetMyHobbyDataSource
import org.sopt.and.data.mapper.Mapper
import org.sopt.and.domain.model.MyHobbyEntity
import org.sopt.and.domain.repository.GetMyHobbyRepository

class GetMyHobbyRepositoryImpl(
private val getMyHobbyDataSource: GetMyHobbyDataSource
) : GetMyHobbyRepository {
override suspend fun getMyHobby(): Result<MyHobbyEntity> =
runCatching {
getMyHobbyDataSource.getMyHobby().result?.let { Mapper.toMyHobbyEntity(it) }!!

Choose a reason for hiding this comment

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

!!는 강제 not null 처리를 해주는 것이기 때문에 null이 들어오는 경우 발생할 예외처리를 해주면 더 좋을 것 같아요

Choose a reason for hiding this comment

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

runCathcing의 onFailure를 사용해서 null에 대한 처리를 해주시거나 이 부분에 관련된 코드들을 다시 하나씩 보시고 null이 발생하지 않게 하면 더 좋은 방법이 될 수 있을 것 같아요.

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.sopt.and.data.repositoryimpl

import org.sopt.and.data.datasource.SignInDataSource
import org.sopt.and.data.mapper.Mapper
import org.sopt.and.domain.model.SignInInformationEntity
import org.sopt.and.domain.model.SignInResponseEntity
import org.sopt.and.domain.repository.SignInRepository

class SignInRepositoryImpl(
private val signInDataSource: SignInDataSource
) : SignInRepository {
override suspend fun signIn(request: SignInInformationEntity): Result<SignInResponseEntity> =
runCatching {
Mapper.toSignInResponseEntity(
signInDataSource.signIn(
Mapper.toSignInRequestDto(
request
)
)
)!!

Choose a reason for hiding this comment

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

이 부분도 널에 대한 처리나 널이 발생하지 않게 해주시면 더 좋을 것 같아요.

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.sopt.and.data.repositoryimpl

import org.sopt.and.data.datasource.SignUpDataSource
import org.sopt.and.data.mapper.Mapper
import org.sopt.and.domain.model.SignUpInformationEntity
import org.sopt.and.domain.model.SignUpResponseEntity
import org.sopt.and.domain.repository.SignUpRepository

class SignUpRepositoryImpl(
private val signUpDataSource: SignUpDataSource
) : SignUpRepository {
override suspend fun signUp(request: SignUpInformationEntity): Result<SignUpResponseEntity> =
runCatching {
Mapper.toSignUpResponseEntity(
signUpDataSource.signUp(
Mapper.toSignUpRequestDto(
request
)
)
)!!
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sopt.and.services
package org.sopt.and.data.service

import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import kotlinx.serialization.json.Json
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sopt.and.services
package org.sopt.and.data.service

import android.content.Context

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sopt.and.services
package org.sopt.and.data.service

import android.content.Context
import kotlinx.coroutines.flow.first
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package org.sopt.and.services
package org.sopt.and.data.service

import android.content.Context
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import org.sopt.and.services.TokenManager.Companion.DATASTORE_NAME
import org.sopt.and.data.service.TokenManager.Companion.DATASTORE_NAME

val Context.dataStore by preferencesDataStore(DATASTORE_NAME)

Expand Down
22 changes: 22 additions & 0 deletions app/src/main/java/org/sopt/and/data/service/UserService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.sopt.and.data.service

import org.sopt.and.data.model.request.SignInRequestDto
import org.sopt.and.data.model.request.SignUpRequestDto
import org.sopt.and.data.model.response.GetMyHobbyResponseDto
import org.sopt.and.data.model.response.SignInResponseDto
import org.sopt.and.data.model.response.SignUpResponseDto
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST

interface UserService {
@POST("/user")
suspend fun signUp(@Body request: SignUpRequestDto): Response<SignUpResponseDto>

@POST("/login")
suspend fun signIn(@Body request: SignInRequestDto): Response<SignInResponseDto>

@GET("/user/my-hobby")
suspend fun getMyHobby(): GetMyHobbyResponseDto
}
5 changes: 5 additions & 0 deletions app/src/main/java/org/sopt/and/domain/model/MyHobbyEntity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.sopt.and.domain.model

data class MyHobbyEntity(
val myHobby: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.sopt.and.domain.model

data class SignInInformationEntity(
val username: String,
val password: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.sopt.and.domain.model

data class SignInResponseEntity(
val token: String? = null,
val status: Int? = null,
val code: String? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.sopt.and.domain.model

data class SignUpInformationEntity(
val username: String,
val password: String,
val hobby: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.sopt.and.domain.model

data class SignUpResponseEntity(
val no: Int? = null,
val code: String? = null,
val status: Int? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.sopt.and.domain.repository

import org.sopt.and.data.datasource.GetMyHobbyDataSource
import org.sopt.and.data.repositoryimpl.GetMyHobbyRepositoryImpl
import org.sopt.and.data.service.ServicePool
import org.sopt.and.domain.model.MyHobbyEntity
Comment on lines +3 to +6
Copy link
Contributor

Choose a reason for hiding this comment

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

domain은 순수한 Kotlin, java 코드로 이루어져야 합니다.
data와 presentation layer에 대한 의존성도 없어야 하고요!


interface GetMyHobbyRepository {
suspend fun getMyHobby(): Result<MyHobbyEntity>

companion object {
fun create(): GetMyHobbyRepositoryImpl {
return GetMyHobbyRepositoryImpl(
GetMyHobbyDataSource(
ServicePool.userService
)

Choose a reason for hiding this comment

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

fun create(
userService: UserService
) 이런식으로 외부에서 서비스를 주입받으면 나중에 서비스를 다른 서비스로 교체하기도 쉽고 코드의 역할이 더 명확할 것 같아요.

ex) create 함수는 단순히 객체를 만드는 부분 / 어떤 서비스를 사용할지는 호출하는 쪽에서 결정하는 식으로..

Copy link
Contributor Author

Choose a reason for hiding this comment

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

음! 좋은 의견인거 같네요! 이해했습니다

)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.sopt.and.domain.repository

import org.sopt.and.data.datasource.SignInDataSource
import org.sopt.and.data.repositoryimpl.SignInRepositoryImpl
import org.sopt.and.data.service.ServicePool
import org.sopt.and.domain.model.SignInInformationEntity
import org.sopt.and.domain.model.SignInResponseEntity
Comment on lines +3 to +7
Copy link
Contributor

Choose a reason for hiding this comment

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

마찬가지에요! 의존성을 잘 고민해봅시다 ~


interface SignInRepository {
suspend fun signIn(request: SignInInformationEntity): Result<SignInResponseEntity>

companion object {
fun create(): SignInRepositoryImpl {
return SignInRepositoryImpl(
SignInDataSource(
ServicePool.userService

Choose a reason for hiding this comment

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

named parameter 사용해주시면 좋을 것 가타요!

)
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.sopt.and.domain.repository

import org.sopt.and.data.datasource.SignUpDataSource
import org.sopt.and.data.repositoryimpl.SignUpRepositoryImpl
import org.sopt.and.data.service.ServicePool
import org.sopt.and.domain.model.SignUpInformationEntity
import org.sopt.and.domain.model.SignUpResponseEntity

interface SignUpRepository {
suspend fun signUp(request: SignUpInformationEntity): Result<SignUpResponseEntity>

companion object {
fun create(): SignUpRepositoryImpl {
return SignUpRepositoryImpl(
signUpDataSource = SignUpDataSource(
userService = ServicePool.userService
)
)
}
}
}
11 changes: 11 additions & 0 deletions app/src/main/java/org/sopt/and/domain/usecase/GetMyHobbyUseCase.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.sopt.and.domain.usecase

import org.sopt.and.domain.model.MyHobbyEntity
import org.sopt.and.domain.repository.GetMyHobbyRepository

class GetMyHobbyUseCase(
private val getMyHobbyRepository: GetMyHobbyRepository
) {
suspend operator fun invoke(): Result<MyHobbyEntity> =

Choose a reason for hiding this comment

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

invoke가 뭔지 공부해보셨나욜?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

네 쓰기전에 알아보고 쓰긴 했는데 왜 usecase에는 invoke를 써야하는지는 모르겠숩니다

getMyHobbyRepository.getMyHobby()
}
12 changes: 12 additions & 0 deletions app/src/main/java/org/sopt/and/domain/usecase/SignInUseCase.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.sopt.and.domain.usecase

import org.sopt.and.domain.model.SignInInformationEntity
import org.sopt.and.domain.model.SignInResponseEntity
import org.sopt.and.domain.repository.SignInRepository

class SignInUseCase(
private val signInRepository: SignInRepository
) {
suspend operator fun invoke(request: SignInInformationEntity): Result<SignInResponseEntity> =
signInRepository.signIn(request = request)
}
Loading