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

[Refactor/#162] ReviewService 부분 Hilt+Flow 리팩토링 #170

Merged
merged 33 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
76e14b5
add: usecase
HI-JIN2 Mar 28, 2024
103545e
feat: service&repository
HI-JIN2 Mar 28, 2024
5ab0b7e
refactor: 리뷰 삭제 리팩토링
HI-JIN2 Mar 28, 2024
63e575b
refactor: 리뷰 수정 리팩토링
HI-JIN2 Mar 28, 2024
402bec0
refactor: 토스트 string
HI-JIN2 Mar 28, 2024
9c3d091
refactor: service&repository
HI-JIN2 Mar 28, 2024
0703c0c
add: 리뷰 리스트&인포 usecase
HI-JIN2 Mar 28, 2024
ef6f4d9
refactor: suspend
HI-JIN2 Mar 29, 2024
5ef72e6
add: 수정/삭제 string
HI-JIN2 Mar 29, 2024
7d537d2
add: 리뷰 요약/리스트 usecase
HI-JIN2 Mar 29, 2024
3a9cd5b
refactor: CA 리팩
HI-JIN2 Mar 29, 2024
11d664a
fix: 수정하기 됨
HI-JIN2 Mar 29, 2024
b7df60d
refactor: 이미지 쪽 리팩
HI-JIN2 Mar 29, 2024
0a947f6
refactor: 리뷰 작성 리팩
HI-JIN2 Mar 29, 2024
85d88fa
refactor: 이미지 변환 content type 헤더
HI-JIN2 Mar 29, 2024
4334962
delete: 이미지 서비스 합치기
HI-JIN2 Mar 29, 2024
be28ff6
chore: 이미지 서비스 정리
HI-JIN2 Mar 29, 2024
f175a88
feat: 로그인 화면 finish() 추가
HI-JIN2 Mar 29, 2024
8ba8265
refactor: timber
HI-JIN2 Apr 2, 2024
321c970
test: 이전 버전
HI-JIN2 Apr 3, 2024
fabfce4
refactor: timber
HI-JIN2 Apr 6, 2024
92737fe
refactor: imageusecase not working
HI-JIN2 Apr 6, 2024
774b229
chore: solved conflict
HI-JIN2 Sep 28, 2024
7f4023b
fix: not load meal's review
HI-JIN2 Sep 28, 2024
c13107e
chore: pretter code
HI-JIN2 Sep 28, 2024
7c82bfa
add: missed rebase
HI-JIN2 Oct 10, 2024
b389ca2
add: debug mode
HI-JIN2 Oct 21, 2024
56fa3b4
chore: 리뷰 반영
HI-JIN2 Oct 23, 2024
e331c9b
chore
HI-JIN2 Oct 25, 2024
aae97b6
package: change usecase folders
HI-JIN2 Nov 18, 2024
e589b47
refactor: 다중 메뉴 선택 뷰 - 뷰모델 리팩토링
HI-JIN2 Nov 18, 2024
00f31a4
chore: @coderabbitai review
HI-JIN2 Nov 18, 2024
57ef195
chore: @coderabbitai review2
HI-JIN2 Nov 18, 2024
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
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ android {
applicationId = "com.eatssu.android"
minSdk = 23
targetSdk = 34
versionCode = 21
versionCode = 22
versionName = "2.1.1"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/java/com/eatssu/android/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class App: Application() {
appContext = this
KakaoSdk.init(this,BuildConfig.KAKAO_NATIVE_APP_KEY)

Timber.plant(Timber.DebugTree())
if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,13 @@ data class MenusInformation(

)

fun MenuOfMealResponse.asMenuOfMeal(): List<MenuMini> {
val menuList = mutableListOf<MenuMini>()

this.menusInformation.forEach {

val menu = MenuMini(it.menuId, it.name)
menuList.add(menu)
}

return menuList
fun MenuOfMealResponse.toMenuMiniList(): List<MenuMini> {
return menusInformation.map { it.toMenuMini() }
}

fun MenusInformation.toMenuMini(): MenuMini {
return MenuMini(
id = this.menuId,
name = this.name
)
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.eatssu.android.data.repository

import com.eatssu.android.base.BaseResponse
import com.eatssu.android.data.dto.response.MenuOfMealResponse
import kotlinx.coroutines.flow.Flow

interface MealRepository {
// suspend fun getTodayMeal(
// date: String,
// restaurant: String,
// time: String,
// ): Flow<BaseResponse<ArrayList<GetMealResponse>>>

suspend fun getMenuInfoByMealId(
mealId: Long,
): Flow<BaseResponse<MenuOfMealResponse>>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.eatssu.android.data.repository

import com.eatssu.android.base.BaseResponse
import com.eatssu.android.data.dto.response.MenuOfMealResponse
import com.eatssu.android.data.service.MealService
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import javax.inject.Inject

class MealRepositoryImpl @Inject constructor(private val mealService: MealService) :
MealRepository {

// override suspend fun getTodayMeal(
// date: String,
// restaurant: String,
// time: String
// ): Flow<BaseResponse<ArrayList<GetMealResponse>>> =
// flow { emit(mealService.getTodayMeal(date, restaurant, time)) }

override suspend fun getMenuInfoByMealId(mealId: Long): Flow<BaseResponse<MenuOfMealResponse>> =
flow {
emit(mealService.getMenuInfoByMealId(mealId))
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,47 @@
package com.eatssu.android.data.repository

import com.eatssu.android.data.service.ReviewService
import com.eatssu.android.base.BaseResponse
import com.eatssu.android.data.dto.request.ModifyReviewRequest
import com.eatssu.android.data.dto.request.WriteReviewRequest
import com.eatssu.android.data.dto.response.GetMealReviewInfoResponse
import com.eatssu.android.data.dto.response.GetMenuReviewInfoResponse
import com.eatssu.android.data.dto.response.GetReviewListResponse
import com.eatssu.android.data.dto.response.ImageResponse
import kotlinx.coroutines.flow.Flow
import okhttp3.MultipartBody

class ReviewRepository(private val reviewService: ReviewService) {
interface ReviewRepository {

// override suspend fun reissueToken(
// refreshToken: String
// ): Flow<ReissueResponse> = flow {
// emit(authService.reissueToken(refreshToken))
// }
suspend fun writeReview(
menuId: Long,
body: WriteReviewRequest,
): Flow<BaseResponse<Void>>

// suspend fun getMenuReviewInfo(menuId: Long)
// : Flow<BaseResponse<GetMenuReviewInfoResponse>> =
// flow {
// emit(reviewService.getMenuReviewInfo(menuId))
// }
suspend fun deleteReview(
reviewId: Long,
): Flow<BaseResponse<Void>>

suspend fun modifyReview(
reviewId: Long,
body: ModifyReviewRequest,
): Flow<BaseResponse<Void>>

suspend fun getReviewList(
menuType: String,
mealId: Long?,
menuId: Long?,
): Flow<BaseResponse<GetReviewListResponse>>

suspend fun getMenuReviewInfo(
menuId: Long,
): Flow<BaseResponse<GetMenuReviewInfoResponse>>


suspend fun getMealReviewInfo(
mealId: Long,
): Flow<BaseResponse<GetMealReviewInfoResponse>>

suspend fun getImageString(
image: MultipartBody.Part,
): Flow<BaseResponse<ImageResponse>>
Comment on lines +15 to +46
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

'suspend' 키워드의 불필요한 사용 검토

'Flow'를 반환하는 함수에서는 일반적으로 'suspend' 키워드가 필요하지 않습니다. 'Flow'는 자체적으로 비동기 스트림을 나타내며, 수집할 때 코루틴 내에서 처리되므로 인터페이스 메서드에서 'suspend'를 제거하여 코드의 간결성과 명확성을 높일 수 있습니다.

적용할 변경 사항:

-    suspend fun writeReview(
+    fun writeReview(

-    suspend fun deleteReview(
+    fun deleteReview(

-    suspend fun modifyReview(
+    fun modifyReview(

-    suspend fun getReviewList(
+    fun getReviewList(

-    suspend fun getMenuReviewInfo(
+    fun getMenuReviewInfo(

-    suspend fun getMealReviewInfo(
+    fun getMealReviewInfo(

-    suspend fun getImageString(
+    fun getImageString(
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
suspend fun writeReview(
menuId: Long,
body: WriteReviewRequest,
): Flow<BaseResponse<Void>>
// suspend fun getMenuReviewInfo(menuId: Long)
// : Flow<BaseResponse<GetMenuReviewInfoResponse>> =
// flow {
// emit(reviewService.getMenuReviewInfo(menuId))
// }
suspend fun deleteReview(
reviewId: Long,
): Flow<BaseResponse<Void>>
suspend fun modifyReview(
reviewId: Long,
body: ModifyReviewRequest,
): Flow<BaseResponse<Void>>
suspend fun getReviewList(
menuType: String,
mealId: Long?,
menuId: Long?,
): Flow<BaseResponse<GetReviewListResponse>>
suspend fun getMenuReviewInfo(
menuId: Long,
): Flow<BaseResponse<GetMenuReviewInfoResponse>>
suspend fun getMealReviewInfo(
mealId: Long,
): Flow<BaseResponse<GetMealReviewInfoResponse>>
suspend fun getImageString(
image: MultipartBody.Part,
): Flow<BaseResponse<ImageResponse>>
fun writeReview(
menuId: Long,
body: WriteReviewRequest,
): Flow<BaseResponse<Void>>
fun deleteReview(
reviewId: Long,
): Flow<BaseResponse<Void>>
fun modifyReview(
reviewId: Long,
body: ModifyReviewRequest,
): Flow<BaseResponse<Void>>
fun getReviewList(
menuType: String,
mealId: Long?,
menuId: Long?,
): Flow<BaseResponse<GetReviewListResponse>>
fun getMenuReviewInfo(
menuId: Long,
): Flow<BaseResponse<GetMenuReviewInfoResponse>>
fun getMealReviewInfo(
mealId: Long,
): Flow<BaseResponse<GetMealReviewInfoResponse>>
fun getImageString(
image: MultipartBody.Part,
): Flow<BaseResponse<ImageResponse>>

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.eatssu.android.data.repository

import com.eatssu.android.base.BaseResponse
import com.eatssu.android.data.dto.request.ModifyReviewRequest
import com.eatssu.android.data.dto.request.WriteReviewRequest
import com.eatssu.android.data.dto.response.GetMealReviewInfoResponse
import com.eatssu.android.data.dto.response.GetMenuReviewInfoResponse
import com.eatssu.android.data.dto.response.GetReviewListResponse
import com.eatssu.android.data.dto.response.ImageResponse
import com.eatssu.android.data.service.ReviewService
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import okhttp3.MultipartBody
import javax.inject.Inject

class ReviewRepositoryImpl @Inject constructor(private val reviewService: ReviewService) :
ReviewRepository {

override suspend fun writeReview(
menuId: Long,
body: WriteReviewRequest,
): Flow<BaseResponse<Void>> =
flow {
emit(reviewService.writeReview(menuId, body))
}

Comment on lines +19 to +26
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

suspend 키워드 제거 제안

각 메서드는 Flow를 반환하므로 suspend 키워드를 제거할 수 있습니다. Flow를 반환하는 함수는 콜드 스트림이므로 호출 시점까지 실행되지 않으며, suspend 없이도 비동기 처리가 가능합니다.

적용할 수 있는 코드 수정 예시:

- override suspend fun writeReview(
+ override fun writeReview(

다른 메서드들도 동일하게 수정할 수 있습니다.

Also applies to: 27-31, 32-39, 40-47, 48-52, 53-57, 58-64

override suspend fun deleteReview(reviewId: Long): Flow<BaseResponse<Void>> =
flow {
emit(reviewService.deleteReview(reviewId))
}

override suspend fun modifyReview(
reviewId: Long,
body: ModifyReviewRequest,
): Flow<BaseResponse<Void>> =
flow {
emit(reviewService.modifyReview(reviewId, body))
}

override suspend fun getReviewList(
menuType: String,
mealId: Long?,
menuId: Long?,
): Flow<BaseResponse<GetReviewListResponse>> = flow {
emit(reviewService.getReviewList(menuType, mealId, menuId))
}

override suspend fun getMenuReviewInfo(menuId: Long): Flow<BaseResponse<GetMenuReviewInfoResponse>> =
flow {
emit(reviewService.getMenuReviewInfo(menuId))
}

override suspend fun getMealReviewInfo(mealId: Long): Flow<BaseResponse<GetMealReviewInfoResponse>> =
flow {
emit(reviewService.getMealReviewInfo(mealId))
}

override suspend fun getImageString(
image: MultipartBody.Part,
): Flow<BaseResponse<ImageResponse>> =
flow {
emit(reviewService.uploadImage(image))
}

Comment on lines +19 to +64
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

에러 처리 로직 추가를 권장드립니다.

현재 구현에서는 서비스 호출 시 발생할 수 있는 예외 상황에 대한 처리가 없습니다. catch 블록을 추가하여 네트워크 오류나 기타 예외 상황을 적절히 처리하는 것이 좋습니다.

예시 코드:

override fun writeReview(
    menuId: Long,
    body: WriteReviewRequest,
): Flow<BaseResponse<Void>> = flow {
-   emit(reviewService.writeReview(menuId, body))
+   try {
+       emit(reviewService.writeReview(menuId, body))
+   } catch (e: Exception) {
+       emit(BaseResponse.error(e.message ?: "알 수 없는 오류가 발생했습니다"))
+   }
}

Committable suggestion skipped: line range outside the PR's diff.

}
18 changes: 0 additions & 18 deletions app/src/main/java/com/eatssu/android/data/service/ImageService.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ interface MealService {
): Call<BaseResponse<ArrayList<GetMealResponse>>>

@GET("meals/{mealId}/menus-info") //메뉴 정보 리스트 조회
fun getMenuInfoByMealId(
suspend fun getMenuInfoByMealId(
@Path("mealId") mealId: Long,
): Call<BaseResponse<MenuOfMealResponse>>
): BaseResponse<MenuOfMealResponse>

}
55 changes: 33 additions & 22 deletions app/src/main/java/com/eatssu/android/data/service/ReviewService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,63 @@ import com.eatssu.android.data.dto.request.WriteReviewRequest
import com.eatssu.android.data.dto.response.GetMealReviewInfoResponse
import com.eatssu.android.data.dto.response.GetMenuReviewInfoResponse
import com.eatssu.android.data.dto.response.GetReviewListResponse
import retrofit2.Call
import retrofit2.http.*
import com.eatssu.android.data.dto.response.ImageResponse
import okhttp3.MultipartBody
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.Multipart
import retrofit2.http.PATCH
import retrofit2.http.POST
import retrofit2.http.Part
import retrofit2.http.Path
import retrofit2.http.Query


interface ReviewService {
@POST("/reviews/write/{menuId}") //리뷰 작성
fun writeReview(
suspend fun writeReview(
@Path("menuId") menuId: Long,
@Body request: WriteReviewRequest,
): Call<BaseResponse<Void>>
): BaseResponse<Void>

@DELETE("/reviews/{reviewId}") //리뷰 삭제
fun deleteReview(
suspend fun deleteReview(
@Path("reviewId") reviewId: Long,
): Call<BaseResponse<Void>>
): BaseResponse<Void>

@PATCH("/reviews/{reviewId}") //리뷰 수정(글 수정)
fun modifyReview(
suspend fun modifyReview(
@Path("reviewId") reviewId: Long,
@Body request: ModifyReviewRequest,
): Call<BaseResponse<Void>>
): BaseResponse<Void>

//Todo paging 라이브러리 써보기
@GET("/reviews") //리뷰 리스트 조회
fun getReviewList(
suspend fun getReviewList(
@Query("menuType") menuType: String,
@Query("mealId") mealId: Long?,
@Query("menuId") menuId: Long?,
// @Query("lastReviewId") lastReviewId: Long?,
// @Query("page") page: Int? =
// @Query("size") size: Int? = 20
// @Query("sort") sort: List<String>? = arrayListOf("date","DESC")
): Call<BaseResponse<GetReviewListResponse>>

// @GET("/reviews/menus/{menuId}") //고정 메뉴 리뷰 정보 조회(메뉴명, 평점 등등)
// fun getMenuReviewInfo(
// @Path("menuId") menuId: Long,
// ): BaseResponse<GetMenuReviewInfoResponse>
@Query("page") page: Int? = 0,
@Query("size") size: Int? = 20,
@Query("sort") sort: List<String>? = arrayListOf("date", "DESC"),
): BaseResponse<GetReviewListResponse>

@GET("/reviews/menus/{menuId}") //고정 메뉴 리뷰 정보 조회(메뉴명, 평점 등등)
fun getMenuReviewInfo(
suspend fun getMenuReviewInfo(
@Path("menuId") menuId: Long,
): Call<BaseResponse<GetMenuReviewInfoResponse>>
): BaseResponse<GetMenuReviewInfoResponse>

@GET("/reviews/meals/{mealId}") //식단(변동 메뉴) 리뷰 정보 조회(메뉴명, 평점 등등)
fun getMealReviewInfo(
suspend fun getMealReviewInfo(
@Path("mealId") mealId: Long,
): Call<BaseResponse<GetMealReviewInfoResponse>>
): BaseResponse<GetMealReviewInfoResponse>

@Multipart
@POST("/reviews/upload/image") //리뷰 이미지 업로드
suspend fun uploadImage(
@Part image: MultipartBody.Part,
): BaseResponse<ImageResponse>

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.eatssu.android.data.usecase
package com.eatssu.android.data.usecase.alarm

import android.app.AlarmManager
import android.app.PendingIntent
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.eatssu.android.data.usecase
package com.eatssu.android.data.usecase.alarm

import com.eatssu.android.data.repository.PreferencesRepository
import kotlinx.coroutines.flow.Flow
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.eatssu.android.data.usecase
package com.eatssu.android.data.usecase.alarm

import com.eatssu.android.data.repository.PreferencesRepository
import javax.inject.Inject
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.eatssu.android.data.usecase
package com.eatssu.android.data.usecase.auth

import android.content.Context
import com.eatssu.android.util.MySharedPreferences
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.eatssu.android.data.usecase
package com.eatssu.android.data.usecase.auth

import com.eatssu.android.base.BaseResponse
import com.eatssu.android.data.dto.response.MyReviewResponse
Expand Down
Loading
Loading