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

[악어] 장바구니 미션 제출합니다. #6

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
64 changes: 29 additions & 35 deletions app/src/main/java/nextstep/shoppingcart/data/Cart.kt
Original file line number Diff line number Diff line change
@@ -1,52 +1,46 @@
package nextstep.shoppingcart.data

import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.runtime.toMutableStateList
import nextstep.shoppingcart.domain.model.CartItem
import nextstep.shoppingcart.domain.model.Product

object Cart {
Copy link

Choose a reason for hiding this comment

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

Cart 에는 레포지토리 패턴을 적용하지 않으신 이유가 있을까요??

Copy link
Author

Choose a reason for hiding this comment

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

product 때까지만 해도 확장성을 열어놓고 생각했었는데요,
만들고 나니 현재로서는 레포지토리 패턴으로 확장하지 않아도 되었겠다는 생각이 들더라구요.
그래서 주어진 Cart 코드로만 작성해봐야겠다 라는 의도로 적용하지 않았습니다...ㅎㅎ

private val _items: MutableList<CartItem> = mutableListOf()
val items: List<CartItem> get() = _items.toList()
val items: SnapshotStateList<CartItem> = emptyList<CartItem>().toMutableStateList()

val totalPrice: Int get() = _items.sumOf { it.totalPrice }

private var maxCartItemId: Long = 0L

fun addOne(product: Product): List<CartItem> {
val item = _items.find { it.product == product }
if (item == null) {
_items.add(
CartItem(
id = fetchMaxCartItemId(),
product = product,
count = 1,
)
)
val totalPrice = mutableIntStateOf(0)

fun addOne(product: Product) {
val item = items.find { it.product == product }
if (item != null) {
val index = items.indexOf(item)
items[index] = item.copy(count = item.count + 1)
} else {
val index = _items.indexOf(item)
_items[index] = item.copy(count = item.count + 1)
items.add(CartItem(product = product, count = 1))
}
return items
updateState()
}

private fun fetchMaxCartItemId(): Long = maxCartItemId++

fun removeOne(product: Product): List<CartItem> {
_items
.find { it.product == product }
?.let { item ->
if (item.count > 1) {
val index = _items.indexOf(item)
_items[index] = item.copy(count = item.count - 1)
} else {
_items.remove(item)
}
fun removeOne(product: Product) {
val item = items.find { it.product == product }
if (item != null) {
if (item.count > 1) {
val index = items.indexOf(item)
items[index] = item.copy(count = item.count - 1)
} else {
items.remove(item)
}
return items
updateState()
}
}

fun removeAll(product: Product) {
items.removeAll { it.product == product }
updateState()
}

fun removeAll(product: Product): List<CartItem> {
_items.removeAll { it.product == product }
return items
private fun updateState() {
totalPrice.value = items.sumOf { it.product.price * it.count }
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package nextstep.shoppingcart.domain.model

data class CartItem(
val id: Long,
val id: Long = maxCartItemId++,
val product: Product,
val count: Int
) {
val totalPrice: Int get() = product.price * count
companion object {
private var maxCartItemId: Long = 0L
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,51 +6,33 @@ import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import nextstep.shoppingcart.data.Cart
import nextstep.shoppingcart.domain.model.CartItem
import nextstep.shoppingcart.domain.model.Product
import nextstep.shoppingcart.presentation.components.screens.CartScreen

class CartActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
var cart by remember { mutableStateOf(Cart) }
var cartItems by remember { mutableStateOf(Cart.items) }
val cartItems = remember { Cart.items }
val totalPrice by Cart.totalPrice
CartScreen(
navigation = { finish() },
cartItems = cartItems,
cart = cart,
onIncrease = {
onIncrease(it)
cartItems = Cart.items
},
onDecrease = {
onDecrease(it)
cartItems = Cart.items
},
onClear = {
onRemove(it)
cartItems = Cart.items
}
totalPrice = totalPrice,
onIncrease = { addItem(it.product) },
onDecrease = { subItem(it.product) },
onClear = { removeItem(it.product) }
)
}
}

private fun addItem(item: Product) = Cart.addOne(item)

private fun onIncrease(item: CartItem) {
Cart.addOne(item.product)
}

private fun onDecrease(item: CartItem) {
Cart.removeOne(item.product)
}
private fun subItem(item: Product) = Cart.removeOne(item)

private fun onRemove(item: CartItem) {
Cart.removeAll(item.product)
}
private fun removeItem(item: Product) = Cart.removeAll(item)

companion object {
fun createIntent(context: Context): Intent = Intent(context, CartActivity::class.java)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package nextstep.shoppingcart.presentation.components
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
Expand Down Expand Up @@ -41,6 +42,7 @@ fun CartItemList(
) {
LazyColumn(
modifier = modifier,
contentPadding = PaddingValues(50.dp)
Copy link

@woowajames woowajames Nov 23, 2024

Choose a reason for hiding this comment

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

Scaffold의 innerPadding과는 어떤 차이점이 있나요? (반복 질문이죠?)
원하는 정보를 찾는 것도 개발자에게 중요한 능력 중 하나이지 않을까요?
원하는 정보가 맞춤형으로 존재하지 않는다면 직접 예제를 구현해서 이런저런 실험을 하면서 깨달을 수도 있다고 생각해요.

정확히 모르겠다고 하셨는데, 그럼 어떤 기준으로 이렇게 사용하셨나요?
그리고 디자인 가이드와 너무 많은 차이가 납니다.

) {
items(
items = items,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,12 @@ import nextstep.signup.R
fun CartScreen(
navigation: () -> Unit,
cartItems: List<CartItem>,
cart: Cart,
totalPrice: Int,
onIncrease: (CartItem) -> Unit = {},
onDecrease: (CartItem) -> Unit = {},
onClear: (CartItem) -> Unit = {},
modifier: Modifier = Modifier,

Choose a reason for hiding this comment

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

이 부분은 여전히 compose api guideline과 일치하지 않네요.

) {
val totalPrice = cartItems.sumOf { it.product.price * it.count }
AndroidshoppingcartTheme {

Choose a reason for hiding this comment

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

현재는 큰 문제가 아닐 수 있지만 테마를 Activity에서 지정하지 않은 이유가 있나요?

Copy link
Author

Choose a reason for hiding this comment

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

#6 (comment)

이 코멘트를 반영하려고 모두 Screen 단위 안으로 Theme을 집어넣었습니다.
아마 위쪽 코멘트에서 제가 의도를 잘못 파악한 것 같군요...!

Scaffold(
modifier = modifier,
Expand Down Expand Up @@ -93,5 +92,5 @@ private fun CartScreenPreview() {
count = 2,
),
)
CartScreen(navigation = {}, cartItems = items, cart = Cart)
CartScreen(navigation = {}, cartItems = items, totalPrice = items.sumOf { it.product.price * it.count })
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fun HomeScreen(
ProductList(
items = products,
onItemClick = onItemClick,
modifier = Modifier.padding(top = 18.dp, start = 13.dp, end = 13.dp)
modifier = Modifier.padding(top = 8.dp, start = 13.dp, end = 13.dp)
)
}
}
Expand Down