-
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
[FEAT/#9] 6주차 과제 #10
base: develop
Are you sure you want to change the base?
[FEAT/#9] 6주차 과제 #10
Conversation
@Provides | ||
@Singleton | ||
fun provideAuthService(retrofit: Retrofit): AuthService = | ||
retrofit.create(AuthService::class.java) |
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.
@Provides | |
@Singleton | |
fun provideAuthService(retrofit: Retrofit): AuthService = | |
retrofit.create(AuthService::class.java) | |
@Provides | |
@Singleton | |
fun provideAuthService(retrofit: Retrofit): AuthService = | |
retrofit.create() |
이런식으로만 작성하셔도 될겁니다
else -> {} | ||
}.onFailure { throwable -> | ||
when (throwable) { | ||
is HttpException -> { |
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.
Presentation 레이어에서 Retrofit의 HttpException을 직접 참조하는 것은 클린 아키텍처 원칙에 어긋날 수 있습니다.
외부 라이브러리에 대한 의존성을 Presentation 레이어에 두게 되면 Retrofit과 같은 네트워크 라이브러리를 다른 라이브러리로 교체할 경우, Presentation 레이어의 코드까지 수정해야 하므로 변경 범위가 커집니다.
이를 방지하기 위해, 데이터 레이어에서 발생하는 예외를 도메인 예외로 매핑하여 전달한 뒤 Presentation 레이어에서 해당 도메인 예외를 처리하는 방식을 권장드립니다.
예를 들어, HttpException을 커스텀 Exception으로 변환하고 Presentation 레이어에서는 해당 Exception만을 참조하도록 구현하면 계층 간 독립성을 유지할 수 있습니다.
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.
자세한 설명 감사합니다. 외부 라이브러리에 대한 의존성에 유의해야 하는 점 꼭 인지하고, 레이어에 따라 로직을 잘 분리할 수 있도록 수정해보겠습니다. 감사합니다 ~
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.
사람마다 clean architecture 적용에 조금씩 차이는 있지만 큰 틀은 변하지 않네요! di 활용 부분에서 많이 배워갑니당ㅎ 수고하셨어요!!
@Provides | ||
@Singleton | ||
fun provideSharedPreferences( | ||
@ApplicationContext context: Context | ||
): SharedPreferences { | ||
return context.getSharedPreferences("APP_PREFS", Context.MODE_PRIVATE) | ||
} |
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.
sharedPreferences 객체를 di를 활용하면 요렇게 관리해줄 수 있군요!!
@@ -0,0 +1,6 @@ | |||
package org.sopt.and.domain.entity |
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.
저는 entity대신 model이라는 네이밍을 사용했는데 혹시 둘 사이에 차이가 있을까요?!
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.
음 저는 개인차라고 생각해요 ! model 네이밍도 좋습니다 ~
import org.sopt.and.core.utils.KeyStorage.ERROR_CODE_00 | ||
import org.sopt.and.core.utils.KeyStorage.STATUS_CODE_200 | ||
import org.sopt.and.core.utils.KeyStorage.STATUS_CODE_401 | ||
import org.sopt.and.core.utils.KeyStorage.STATUS_CODE_403 | ||
import org.sopt.and.core.utils.KeyStorage.STATUS_CODE_404 | ||
import org.sopt.and.core.utils.KeyStorage.TOKEN |
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.
상수화 굿이네요......👍
@HiltViewModel | ||
class MyPageViewModel @Inject constructor( | ||
private val authRepository: AuthRepository, | ||
private val sharedPreferences: SharedPreferences |
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.
di에서 sharedPreferences 객체를 제공하면 요런식으로 의존성을 주입할 수 있군용
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.
워낙 견고하게 잘 짜주셔서 제가 더 많이 배워갑니다!
import org.sopt.and.data.dto.response.ResponseSignInDto | ||
import org.sopt.and.data.dto.response.ResponseSignUpDto | ||
|
||
interface AuthDataSource { |
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.
Auth기능과 getBobby 구현이 한 DataSource파일에 합쳐진 것 같아서 나중에는 분리해서 제작하는 것도 좋아보여요!
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.
오 넵 참고할게요-! 감사합니다
val errorBody = throwable.response()?.errorBody()?.string() | ||
val errorDto = errorBody?.let { Json.decodeFromString<ResponseErrorDto>(it) } | ||
val statusCode = throwable.code() | ||
val errorCode = errorDto?.code.orEmpty() | ||
handleError(statusCode, errorCode) | ||
} | ||
else -> {} |
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.
꼼꼼하게 해주셨군요!
@@ -59,15 +64,15 @@ class SignUpViewModel : ViewModel() { | |||
return | |||
} | |||
|
|||
val request = RequestSignUpDto( | |||
val request = SignUpModel( | |||
username = username.value, | |||
password = password.value, | |||
hobby = hobby.value | |||
) | |||
|
|||
viewModelScope.launch { | |||
runCatching { |
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.
말씀해주신 runCatching을 사용해서 구현해봤는데 가독성이 훨씬 높아지더라구요!
|
||
suspend fun signIn(request: SignInModel): Result<String> | ||
|
||
suspend fun getHobby(request: String): Result<String> |
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.
String을 사용해도 좋지만 추후에 어떻게 될지 모르니 DataClass를 사용하는게 좋아보여요!
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.
고생하셨습니다 ~
hilt { | ||
enableAggregatingTask = false | ||
} |
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.
이 친구를 왜 추가해야할까요?
추가를 하지 않고도 할 수 있는데 어떻게 수정하면 좋을까요?
import org.sopt.and.core.utils.KeyStorage.AUTH_PREFS | ||
import org.sopt.and.core.utils.KeyStorage.HOME | ||
import org.sopt.and.core.utils.KeyStorage.SIGN_IN | ||
import org.sopt.and.core.utils.KeyStorage.SIGN_UP |
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.
보통 core 패키징에는 어떤 친구들을 넣어두시는지 궁금합니다 ~
@Provides | ||
@Singleton | ||
fun provideSharedPreferences( | ||
@ApplicationContext context: Context | ||
): SharedPreferences { | ||
return context.getSharedPreferences("APP_PREFS", Context.MODE_PRIVATE) | ||
} |
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.
Network에 관련된 친구라고 보기는 애매해서 따로 Module을 분리해주어도 좋을 것 같네요
Related issue 🛠
Work Description ✏️
필수 과제
심화 과제
도전 과제
Screenshot 📸
PR #8과 동일합니다.
Uncompleted Tasks 😅
To Reviewers 📢
Clean Architecture와 Hilt 적용했습니다!
합세 리뷰에서, Domain layer는 Data layer로의 의존성이 없어야 한다, 즉 data와 연관된 import도 있으면 안 된다는 팟장님의 말씀을 듣고, 그 부분은 꼭 적용하자는 생각으로 진행해본 것 같아요!
절대 Repository에서 dto를 바로 쓰면 안된다 .. model을 형성하여 써야 한다 .. 메모메모 .. (저번 앱잼에서도 정말 많이 들은 이야기랍니당)
아키텍처와 DI 적용에 있어서 제 코드와 의견이 다르신 부분이나, 조언 있으시면 마구마구 리뷰 부탁드립니다-! 🤩