- vừa được xem lúc

Hạn chế sử dụng "when" càng nhiều càng tốt, thay vào đó hãy sử dụng tính đa hình

0 0 10

Người đăng: Hùng Bá Nguyễn

Theo Viblo Asia

Một tips nhỏ cho lập trình viên Android

Câu lệnh when thường bị coi là code xấu và nên tránh.

Giả sử Button cần phát triển với 5 kích thước được xác định trước:

  • small (height = 16dp)
    
  • medium (height = 24dp)
    
  • large (height = 32dp)
    
  • huge (height = 40dp)
    
  • custom
    
sealed class ButtonSize { object Small : ButtonSize() object Medium : ButtonSize() object Large : ButtonSize() object Huge : ButtonSize() data class Custom(val heightDpInt: Int) : ButtonSize()
} @Composable
fun RenderButton( buttonSize: ButtonSize, onButtonClick: () -> Unit, text: String
) { Button( modifier = Modifier.height(buttonSize.getButtonHeight()).fillMaxWidth(), onClick = onButtonClick, content = { Text(text = text) } )
} private fun ButtonSize.getButtonHeight(): Dp { return when (this) { ButtonSize.Small -> 16.dp ButtonSize.Medium -> 24.dp ButtonSize.Large -> 32.dp ButtonSize.Huge -> 40.dp is ButtonSize.Custom -> this.heightDpInt.dp }
}

Hãy nhìn kỹ hơn hàm getButtonHeight và hiểu điều gì sai ở đây.

private fun ButtonSize.getButtonHeight(): Dp { return when (this) { // Useless checking type ButtonSize.Small -> 16.dp // code duplication ButtonSize.Medium -> 24.dp // code duplication ButtonSize.Large -> 32.dp // code duplication ButtonSize.Huge -> 40.dp // code duplication is ButtonSize.Custom -> this.heightDpInt.dp // code duplication }
}

Hai vấn đề liên quan đến sự trùng lặp code:

  • Khởi tạo Dp từ Int
  • Thêm việc kiểm tra lúc runtime. Chúng ta đã quyết định trong ViewModel chiều cao của Button nên được sử dụng. Tại sao lại phải kiểm tra thêm? Nó vô dụng. Hơn nữa, nó làm tăng thời gian chạy. Tài nguyên của điện thoại Android có thể được sử dụng cho các hoạt động khác có giá trị hơn - ví dụ: chạy animation.
class ViewModel( // ...
): ViewModel(){ val buttonSizeLiveData = MutableLiveData<ButtonSize>() // ... private fun methodThatDoesSomething() { // ... buttonSizeLiveData.post(ButtonSize.Small) // Here we decided what size should be rendered // ... } // ...
} private fun ButtonSize.getButtonHeight(): Dp { val heightInt = when (this) { ButtonSize.Small -> 16 // Code duplication! Type-checking should be avoided! ButtonSize.Medium -> 24 ButtonSize.Large -> 32 ButtonSize.Huge -> 40 is ButtonSize.Custom -> this.heightDpInt } return heightInt.dp // Here we fixed the 1st code duplication problem
}

Hãy loại bỏ việc kiểm tra. Tất cả những gì chúng ta nên làm là thay thế "when" bằng đa hình.

/* * Here we moved dp values from getButtonHeight method. * getButtonHeight method has been removed. */
sealed class ButtonSize(open val heightDpInt: Int) { object Small : ButtonSize(16) object Medium : ButtonSize(24) object Large : ButtonSize(32) object Huge : ButtonSize(40) data class Custom(override val heightDpInt: Int): ButtonSize(heightDpInt) fun getHeightDp(): Dp { return heightDpInt.dp }
} @Composable
fun RenderButton( buttonSize: ButtonSize, onButtonClick: () -> Unit, text: String
) { Button( modifier = Modifier.height(buttonSize.getHeightDp()).fillMaxWidth(), onClick = onButtonClick, content = { Text(text = text) } )
}

Hãy làm cho ví dụ phức tạp hơn. Giả sử rằng văn bản (text) và màu chữ của Button phụ thuộc vào ButtonSize. Chúng tôi sẽ xem xét cả hai trường hợp. So sánh hai đoạn mã dưới đây:

sealed class ButtonSize( open val heightDpInt: Int, open val color: Color, open val textResId: Int
) { object Small : ButtonSize(16, Color.Red, R.string.small_button_text) object Medium : ButtonSize(24, Color.Gray, R.string.medium_button_text) object Large : ButtonSize(32, Color.Green, R.string.large_button_text) object Huge : ButtonSize(40, Color.Blue, R.string.huge_button_text) data class Custom( override val heightDpInt: Int, override val color: Color, override val textResId: Int ) : ButtonSize(heightDpInt, color, textResId) fun getHeightDp(): Dp { return heightDpInt.dp }
} @Composable
fun RenderButton( buttonSize: ButtonSize, onButtonClick: () -> Unit
) { Button( modifier = Modifier .height(buttonSize.getHeightDp()) .fillMaxWidth(), onClick = onButtonClick, colors = ButtonDefaults.buttonColors( backgroundColor = buttonSize.color, ), content = { Text(text = stringResource(buttonSize.textResId)) } )
}
Ví dụ với tính đa hình
sealed class ButtonSize() { object Small : ButtonSize() object Medium : ButtonSize() object Large : ButtonSize() object Huge : ButtonSize() data class Custom( val heightDpInt: Int, val color: Color, val textResId: Int ) : ButtonSize()
} @Composable
fun RenderButton( buttonSize: ButtonSize, onButtonClick: () -> Unit
) { Button( modifier = Modifier .height(buttonSize.getButtonHeight()) .fillMaxWidth(), onClick = onButtonClick, colors = ButtonDefaults.buttonColors( backgroundColor = buttonSize.getButtonColor(), ), content = { Text(text = stringResource(buttonSize.getButtonText())) } )
} private fun ButtonSize.getButtonHeight(): Dp { return when (this) { ButtonSize.Small -> 16 // Code duplication ButtonSize.Medium -> 24 // Code duplication ButtonSize.Large -> 32 // Code duplication ButtonSize.Huge -> 40 // Code duplication is ButtonSize.Custom -> this.heightDpInt // Code duplication }
} private fun ButtonSize.getButtonText(): Int { return when (this) { ButtonSize.Small -> R.string.small_button_text // Code duplication ButtonSize.Medium -> R.string.medium_button_text // Code duplication ButtonSize.Large -> R.string.large_button_text // Code duplication ButtonSize.Huge -> R.string.huge_button_text // Code duplication is ButtonSize.Custom -> this.textResId // Code duplication }
} private fun ButtonSize.getButtonColor(): Color { return when (this) { ButtonSize.Small -> Color.Red // Code duplication ButtonSize.Medium -> Color.Gray // Code duplication ButtonSize.Large -> Color.Green // Code duplication ButtonSize.Huge -> Color.Blue // Code duplication is ButtonSize.Custom -> this.color // Code duplication }
}
Ví dụ với biểu thức "when"

Lợi ích của Đa hình:

  •  Nó làm cho codebase nhỏ hơn.
    
  •  Nó là dễ dàng hơn để mở rộng chức năng.
    
  •  Nó giúp loại bỏ sự trùng lặp mã.
    
  •  Nó làm giảm chi phí thời gian chạy.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Học Flutter từ cơ bản đến nâng cao. Phần 1: Làm quen cô nàng Flutter

Lời mở đầu. Gần đây, Flutter nổi lên và được Google PR như một xu thế của lập trình di động vậy.

0 0 254

- vừa được xem lúc

Học Flutter từ cơ bản đến nâng cao. Phần 3: Lột trần cô nàng Flutter, BuildContext là gì?

Lời mở đầu. Màn làm quen cô nàng FLutter ở Phần 1 đã gieo rắc vào đầu chúng ta quá nhiều điều bí ẩn về nàng Flutter.

0 0 189

- vừa được xem lúc

[Android] Hiển thị Activity trên màn hình khóa - Show Activity over lock screen

Xin chào các bạn, Hôm nay là 30 tết rồi, ngồi ngắm trời chờ đón giao thừa, trong lúc rảnh rỗi mình quyết định ngồi viết bài sau 1 thời gian vắng bóng. .

0 0 93

- vừa được xem lúc

Tìm hiểu Proguard trong Android

1. Proguard là gì . Cụ thể nó giúp ứng dụng của chúng ta:. .

0 0 82

- vừa được xem lúc

Làm ứng dụng học toán đơn giản với React Native - Phần 6

Chào các bạn một năm mới an khang thịnh vượng, dồi dào sức khỏe. Lại là mình đây Đây là link app mà các bạn đang theo dõi :3 https://play.google.com/store/apps/details?id=com.

0 0 51

- vừa được xem lúc

20 Plugin hữu ích cho Android Studio

1. CodeGlance. Plugin này sẽ nhúng một minimap vào editor cùng với thanh cuộn cũng khá là lớn. Nó sẽ giúp chúng ta xem trước bộ khung của code và cho phép điều hướng đến đoạn code mà ta mong muốn một cách nhanh chóng.

0 0 301