-
Notifications
You must be signed in to change notification settings - Fork 0
Week6 assignment #10
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
base: develop
Are you sure you want to change the base?
Week6 assignment #10
Conversation
|
์ด์ ์ฃผ์ฐจ (week4) ๊ณผ์ ๊น์ง ์ด๋ฒ์ ํ ๋ฒ์ ์งํํด์ ๋จธ์ง๊ฐ ์ ๋ ์ํ๋ผ ์ด๋ฒ์๋ ํ์ผ ํธ๋ํน์ด ๋ค ์์ฌ๋ฒ๋ ค์ ์ฝ๋ ๋ฆฌ๋ทฐ ์งํํ์๊ธฐ๊ฐ ์ด๋ ค์ฐ์ค ๊ฒ ๊ฐ์์..ใ ใ ๋๋ต์ ์ผ๋ก data ํจํค์ง์ datalocal, dataremote, di ํจํค์ง, domain/repository ํจํค์ง์ UserRepository, usecase ํจํค์ง ํ์ ํ์ผ๋ค ํ์ธํด์ฃผ์๋ฉด ๋ ๊ฒ ๊ฐ์ต๋๋ค..! |
chattymin
left a comment
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.
6์ฃผ์ฐจ ๊ณผ์ ์๊ณ ํ์
จ์ต๋๋ค!!
clean architecture์ ๋ํด์ ํ๋ฒ ๋ ๊ณต๋ถํด๋ณด์๊ณ ๋ฆฌํํ ๋ง ์งํํด๋ณด์๋ฉด ์ข์ ๊ฒ ๊ฐ์์!
์๋ก์ด ๊ธฐ์ ์ ๋ฐฐ์์ ์ฐ๋ ๊ฒ๋ ์ข์ง๋ง, ๊ธฐ์กด์ ๊ธฐ์ ์ ์ ์๊ณ ์ฌ์ฉํ๋๊ฒ ์ ๋ง์ ๋ง ์ค์ํ๋ค๊ณ ์๊ฐํด์. ์ฑ์ผ์ด ๋ค๊ฐ์ค๊ณ ์๋๋ฐ ์ฑ์ผ ์ ์ ์ง๊ธ๊น์ง ๋ฐฐ์ด ๊ฒ๋ค์ ํ๋ฒ ๋ณต์ตํ๋ ์๊ฐ์ ๊ฐ์ ธ๋ณธ๋ค๋ฉด ์ฑ์ผ๋ ์ ๋ง ํฐ ๋์์ด ๋ ๊ฑฐ์์ :)
| import org.sopt.and.data.dataremote.model.request.RequestCreateUserDto | ||
| import org.sopt.and.data.dataremote.model.request.RequestGetUserDto | ||
| import org.sopt.and.data.dataremote.model.response.ResponseCreateUserSuccessDto | ||
| import org.sopt.and.data.dataremote.model.response.ResponseGetUserDto | ||
| import org.sopt.and.data.dataremote.model.response.ResponseGetUserHobbyDto | ||
| import retrofit2.Response |
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.
domain์ธ๋ฐ data layer์ ์์กด์ฑ์ ๊ฐ์ง๊ณ ์์ด์.
๊ทธ๋ฆฌ๊ณ retrofit์ ๋ํ ์์กด์ฑ๋ ๊ฐ์ง๊ณ ์์ด์.
domain๋ชจ๋์ kotlin/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.
์์กด์ฑ ๋ถ๋ฆฌ๋ผ๋ ์๋ ๋ชฉ์ ์ ์๊ฐํ๋ฉด์ ๋ฆฌํฉํ ๋งํด๋ณด๋, ํด๋ฆฐ ์ํคํ ์ฒ๊ฐ ์งํฅํ๋ ๊ตฌ์กฐ์ ๋ํด์ ์กฐ๊ธ ๋ ๊ฐ์ด ์กํ๋ ๊ฒ ๊ฐ์์. ๋ฆฌ๋ทฐ ๊ฐ์ฌํฉ๋๋ค!!
t1nm1ksun
left a comment
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.
6,7์ฃผ์ฐจ ๋ด์ฉ ์ ๋ ์๋นํ ์ด๋ ต๋๋ฐ ๊ณ ์๋ง์ผ์
จ์ต๋๋ค!
์ด์ ๊ณง ์ฑ์ผํ์ค ํ
๋ฐ ํ์ดํ
์
๋๋ค!!
| data class LoginScreen( | ||
| val emailText: String, | ||
| val userNameText: String, | ||
| val passwordText: 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.
์๋์ ์๋ ๋ก๊ทธ์ธํ๋ฉด๊ณผ ๋ค์ด๋ฐ์ด ๋๊ฐ์์ ํท๊ฐ๋ฆด ์ ์์๊ฑฐ๊ฐ์์!
๊ทธ๋ฆฌ๊ณ ๋ง์ฝ ์ฌ์ฉํ๋๊ณณ์ด๋ ๋ค๋ฅธ data class๋ค์ด ๋ง์์ง๋ค๋ฉด ๋ฐ๋ก ํด๋๋ฅผ ์์ฑํด์ ๊ด๋ฆฌํ๋๊ฒ๋ ์ข์ต๋๋ค!
| ) : ViewModel() { | ||
|
|
||
| //๋ก๊ทธ์ธ ์์ฒญ์ ์๋ฒ๋ก ๋ณด๋ด๊ธฐ ์ํจ | ||
| private val userService by lazy { ServicePool.userService } |
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.
UseCase๋ฅผ ํตํด ์๋ฒํต์ ์ ๋ง๋ค์ด ๋์์ผ๋ ์ด์ ํด๋น ์ฝ๋๋ ์ฌ์ฉ๋์ง ์์ ๊ฒ ๊ฐ์์!
| fun StringInputValidCheck(newString: String): Boolean { | ||
| var isValid = false | ||
| val inputStr : CharSequence = email | ||
| val pattern = Patterns.EMAIL_ADDRESS | ||
| val matcher = pattern.matcher(inputStr) | ||
| if(matcher.matches()){ | ||
| isValid = true | ||
| val inputStr : CharSequence = newString | ||
|
|
||
| if(inputStr.length >= 8){ | ||
| return isValid | ||
| } else { | ||
| return !isValid | ||
| } | ||
| return isValid | ||
| } | ||
|
|
||
| fun PasswordValidCheck(password: String): Boolean { | ||
| val pattern = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)|(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#\$%^&*])|(?=.*[a-z])(?=.*\\d)(?=.*[!@#\$%^&*])|(?=.*[A-Z])(?=.*\\d)(?=.*[!@#\$%^&*]).{8,20}\$".toRegex() | ||
| val pattern = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)|(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#\$%^&*])|(?=.*[a-z])(?=.*\\d)(?=.*[!@#\$%^&*])|(?=.*[A-Z])(?=.*\\d)(?=.*[!@#\$%^&*]).{1,8}\$".toRegex() | ||
| return password.matches(pattern) | ||
|
|
||
| } |
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.
validateUserInputUseCase์ ์ ํจ์ฑ ๊ฒ์ฆ ๋ก์ง์ ์ฎ๊ฒจ์ domain ๋ ์ด์ด๋ก ๋ถ๋ฆฌํ์ต๋๋ค!! ๊ผผ๊ผผํ ๋ฆฌ๋ทฐ ๊ฐ์ฌํฉ๋๋ค ๐ฅฒ
| ) : ViewModel() { | ||
|
|
||
| //๋ก๊ทธ์ธ ์์ฒญ์ ์๋ฒ๋ก ๋ณด๋ด๊ธฐ ์ํจ | ||
| private val userService by lazy { ServicePool.userService } |
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๋ฅผ ์ฌ์ฉํ๊ณ ์๋๋ฐ ServicePool์ ์ง์ ์ฐธ์กฐํ๋ ๊ฒ์ DI ์์น์ ์๋ฐฐ๋ฉ๋๋ค!
๋ฏผ์์ด ์ฝ๋ฉํธ ์ฒ๋ผ ์ฌ์ฉํ์ง ์๋ ์ฝ๋๋ ์ ๊ฑฐ ํด๋ ์ข์ ๊ฒ ๊ฐ๋ค์
| private val _loginResult = MutableStateFlow<Boolean?>(null) | ||
| val loginResult = _loginResult.asStateFlow() |
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.
| private val _loginResult = MutableStateFlow<Boolean?>(null) | |
| val loginResult = _loginResult.asStateFlow() | |
| sealed class LoginUiState { | |
| object Initial : LoginUiState() | |
| object Success : LoginUiState() | |
| data class Error(val message: String) : LoginUiState() | |
| } | |
| private val _loginState = MutableStateFlow<LoginUiState>(LoginUiState.Initial) | |
| val loginState = _loginState.asStateFlow() |
Boolean? ๋์ sealed class๋ฅผ ์ฌ์ฉํ์ฌ ์ํ๋ฅผ ๋ ๋ช ํํ๊ฒ ํํํ ์ ์์ด์!
| _shouldShowPassword.value = !_shouldShowPassword.value | ||
| } | ||
|
|
||
| // ์ ๋ ฅ๊ฐ์ด ์กฐ๊ฑด์ ๋ง๋์ง ํ์ธ (๋ ๋ค ์ฌ๋ ์ ์ดํ?) |
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.
์ ํจ์ฑ ๊ฒ์ฌ ๋ก์ง์ ๋ณ๋์ UseCase๋ ๋ค๋ฅธ ํด๋์ค๋ก ๋ถ๋ฆฌํ๋๊ฒ ์ข์๋ณด์ฌ์
| _user.value.name = userName | ||
| _user.value.hobby = hobby | ||
| _user.value.accessToken = accessToken |
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.
| _user.value.name = userName | |
| _user.value.hobby = hobby | |
| _user.value.accessToken = accessToken | |
| _user.value = _user.value.copy( | |
| name = userName, | |
| hobby = hobby, | |
| accessToken = accessToken | |
| ) |
์ง์ ํ๋ ์์ ์ ๊ถ์ฅ๋์ง ์๋๊ฑธ๋ก ์์์ ์๋ ๊ฒ ํด๋ณด๋๊ฑด ์ด๋์?
| private val postSignUpUseCase: PostSignUpUseCase | ||
| ) : ViewModel() { | ||
|
|
||
| private val userService by lazy { ServicePool.userService } |
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.
ServicePool์ ํตํด UserService๋ฅผ ๊ฐ์ ธ์ค๋ ๋์ , ์์ฑ์๋ฅผ ํตํ ์์กด์ฑ ์ฃผ์ ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค
private val userService by lazy { ServicePool.userService }
โ
@Inject constructor(
private val userService: UserService,
private val postSignUpUseCase: PostSignUpUseCase
)
| return _isUserNameValid.value && _isPasswordValid.value | ||
| } | ||
|
|
||
| suspend fun createNewUser() { |
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.
createNewUser() ํจ์๊ฐ ๋๋ฌด ๋ง์ ์ผ์ ํ๊ณ ์๋๊ฒ ๊ฐ์์. ์๋ฌ ์ฒ๋ฆฌ ๋ก์ง์ ๋ณ๋์ private ํจ์๋ก ๋ถ๋ฆฌํ๋ฉด ์ฝ๋ ๊ฐ๋ ์ฑ์ด ๋ ์ข์์ง ๊ฒ ๊ฐ์ต๋๋ค. ์ง๊ธ๋ณด๋ค ํจ์ฌ ๊น๋ํด์ง ๊ฑฐ์์!
angryPodo
left a comment
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.
์ง์์ ๊ณ ์ ๋ง์๋คใ
์ฝํ๋ฆฐ๋ ์ ์ต์ํ๋ฐ ์ด ์ ๋๋ก ์ ์ฉํ ๊ฑฐ ๋ณด๋ฉด ์ง์ง ๋๊ฒฌํ๋ค! ์ํคํ
์ฒ ํจํด์ด๋ ๋ก์ง ๋ถ๋ฆฌ๋ ๋๋ ์์ง๋ ๊ฐ์ด ์ ์ ์ค๋ ๋ถ๋ถ์ด๋ผ... ์ฑ์ผ ํ๋ฉด์ ์ค์ ์ผ๋ก ๋ถ๋ชํ๋ณด๋ฉด ์ ์จ์ผ ํ๋์ง ๋ ์๋ฟ์ ๊ฑฐ๊ณ , ๊ทธ ๋ค์๋ถํฐ ์์ฐ์ค๋ฝ๊ฒ ๋ฐ์ ์์ผ๋๊ฐ ์ ์์ ๊ฑฐ์ผ.๋ง์ง๋ง๊น์ง ํ๋ด๋ณด์!
jihyunniiii
left a comment
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.dataremote.model.response.ResponseGetUserHobbyDto | ||
| import org.sopt.and.domain.repository.UserRepository |
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.
domain ๋ ์ด์ด์ธ๋ฐ data์ ๋ํ ์์กด์ฑ์ ๊ฐ์ง๊ณ ์์ด์.
์ธ๋ฏธ๋ ๋ ๋ฐฐ์ด ์์กด์ฑ์ ๋ฐํ์ผ๋ก ์ด๋ป๊ฒ ์์ ํ๋ฉด ์ข์์ง ๊ณ ๋ฏผํด๋ด
์๋ค.
|
|
||
| import org.sopt.and.data.dataremote.model.response.ResponseGetUserHobbyDto | ||
| import org.sopt.and.domain.repository.UserRepository | ||
| import retrofit2.Response |
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.
๋ง์ฐฌ๊ฐ์ง๋ก domain ๋ ์ด์ด๋ ์์ํ java, kotlin ์ฝ๋๋ก ์ด๋ฃจ์ด์ ธ์ผ ํฉ๋๋ค.
|
|
||
| var emailState = remember { mutableStateOf(inputEmail) } | ||
| var passwordState = remember { mutableStateOf(inputPassword) } | ||
| var isUserNameValid = loginViewModel.isUserNameValid.collectAsState().value |
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.
collectAsState์ collectAsStateWithLifecycle์ ์ฐจ์ด๋ ๋ฌด์์ผ๊น์?
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.
collectAsStateWithLifecycle์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ํ์ฒ๋ผ ํ๋ฉด์ด ํ์ฑํ๋์ง ์์์ ๋๋ ๊ตณ์ด State๋ฅผ ๊ณ์ ๊ด์ฐฐํ๊ณ ์์ง ์์์ ์กฐ๊ธ ๋ ํจ์จ์ ์ผ๋ก ์ํ๋ฅผ ๊ด๋ฆฌํ ์ ์๋ ๊ฒ์ผ๋ก ์๊ณ ์์ต๋๋ค!
๋งค๋ฒ collectAsStateWithLifecycle์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ฌด์กฐ๊ฑด ์ข์ง๋ง์ ์์ ๊ฒ ๊ฐ์์, ๊ตฌ๋ ํ๊ณ ์๋ StateFlow๊ฐ ์ผ๋ง๋ ์์ฃผ ๋ณ๊ฒฝ๋๋ ๊ฐ์ธ์ง? ๋ฑ์ ๊ณ ๋ คํด์ ์ฌ์ฉํ๋ ๋ฒ์ ์ตํ๋ ๊ฒ ์ข์ ๊ฒ ๊ฐ์ต๋๋ค
| import org.sopt.and.data.datalocal.datasource.UserInfoLocalDataSource | ||
| import org.sopt.and.data.dataremote.network.ServicePool |
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.
๋ฆฌ๋ทฐ ๋ฐ์ํด์ ์์กด์ฑ์ ๋ํด ๊ณ ๋ฏผํด๋ณด๊ณ ๋ชจ๋ Viewmodel์์ data ๋ ์ด์ด ๊ด๋ จ ์์กด์ฑ ์ ๊ฑฐํ์ต๋๋ค! (UseCase -> UserRepositoryImpl์ผ๋ก ๋ถ๋ฆฌ)
| navController.navigate(Route.SearchScreen) | ||
| } | ||
| "profile" -> { | ||
| navController.navigate(Route.MypageScreen(userName = "")) /*username์ ์ฌ๊ธฐ๋ค ์ด๋ป๊ฒ ๋ฃ์ด์ฃผ์ง?*/ |
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.
Route sealed class๋ฅผ ์ด๋ป๊ฒ ํ์ฉํ๋ฉด ๊ฐ์ ๋ฃ์ด์ค ์ ์์์ง ์๊ฐํด๋ณด์ธ์!
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.
์ธ๋ฏธ๋ ์๋ฃ ์ฐธ๊ณ ํด๋ณด์ ์!!
Related issue ๐
Work Description โ๏ธ
Screenshot ๐ธ
Uncompleted Tasks ๐
To Reviewers ๐ข