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

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 classButtonSize{ object Small:ButtonSize()

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 classButtonSize{
    object Small:ButtonSize()
    object Medium:ButtonSize()
    object Large:ButtonSize()
    object Huge:ButtonSize()
    data classCustom(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{returnwhen(this){ButtonSize.Small->16.dp
        ButtonSize.Medium->24.dp
        ButtonSize.Large->32.dp
        ButtonSize.Huge->40.dp
        isButtonSize.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.
classViewModel(// ...):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->24ButtonSize.Large->32ButtonSize.Huge->40isButtonSize.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.
 */sealedclass ButtonSize(open val heightDpInt:Int){object Small : ButtonSize(16)object Medium : ButtonSize(24)object Large : ButtonSize(32)object Huge : ButtonSize(40)
    data class Custom(overrideval 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:

sealedclass 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(overrideval heightDpInt:Int,overrideval color: Color,overrideval 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 classButtonSize(){
    object Small:ButtonSize()
    object Medium:ButtonSize()
    object Large:ButtonSize()
    object Huge:ButtonSize()
    data classCustom(
        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{returnwhen(this){ButtonSize.Small->16// Code duplicationButtonSize.Medium->24// Code duplicationButtonSize.Large->32// Code duplicationButtonSize.Huge->40// Code duplicationisButtonSize.Custom-> this.heightDpInt // Code duplication}}private fun ButtonSize.getButtonText():Int{returnwhen(this){ButtonSize.Small->R.string.small_button_text // Code duplicationButtonSize.Medium->R.string.medium_button_text // Code duplicationButtonSize.Large->R.string.large_button_text // Code duplicationButtonSize.Huge->R.string.huge_button_text // Code duplicationisButtonSize.Custom-> this.textResId // Code duplication}}private fun ButtonSize.getButtonColor():Color{returnwhen(this){ButtonSize.Small->Color.Red// Code duplicationButtonSize.Medium->Color.Gray// Code duplicationButtonSize.Large->Color.Green// Code duplicationButtonSize.Huge->Color.Blue// Code duplicationisButtonSize.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.

Nguồn: viblo.asia

Bài viết liên quan

Thay đổi Package Name của Android Studio dể dàng với plugin APR

Nếu bạn đang gặp khó khăn hoặc bế tắc trong việc thay đổi package name trong And

Lỗi không Update Meta_Value Khi thay thế hình ảnh cũ bằng hình ảnh mới trong WordPress

Mã dưới đây hoạt động tốt có 1 lỗi không update được postmeta ” meta_key=

Bài 1 – React Native DevOps các khái niệm và các cài đặt căn bản

Hướng dẫn setup jenkins agent để bắt đầu build mobile bằng jenkins cho devloper an t

Chuyển đổi từ monolith sang microservices qua ví dụ

1. Why microservices? Microservices là kiến trúc hệ thống phần mềm hướng dịch vụ,