首页 > 解决方案 > 不要每次都创建 valueEventListener

问题描述

我如何优化我的代码?在我创建的每个函数valueEventListener中。

这是所有代码:

class TargetsPresenter(private val contract: SelectTargetViewContract) {

    var firebaseUser: FirebaseUser? = null
    var targetList: ArrayList<Goal> = ArrayList()
    private var databaseReference: DatabaseReference? = null
    private var targetsRef: DatabaseReference? = null
    private var uid: String? = null

    fun setInitialData() {
        firebaseUser = FirebaseAuth.getInstance().currentUser
        databaseReference = FirebaseDatabase.getInstance().reference
        uid = firebaseUser?.uid
        targetsRef = databaseReference?.child("targets")
            ?.child("users")?.child(uid.toString())
            ?.child("targets")
    }

    fun getTargetsFromDb() {
        val valueEventListener = object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                targetList.clear()
                dataSnapshot.children
                    .mapNotNull { it.getValue(Goal::class.java) }
                    .toCollection(targetList)
                contract.updateViewContent()
            }

            override fun onCancelled(databaseError: DatabaseError) {
                Log.d("some", "Error trying to get targets for ${databaseError.message}")
            }
        }
        targetsRef?.addListenerForSingleValueEvent(valueEventListener)
    }

    fun getTargetsByPriority() {
        val valueEventListener = object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                targetList.clear()
                dataSnapshot.children
                    .mapNotNull { it.getValue(Goal::class.java) }
                    .sortedBy { it.priority }
                    .toCollection(targetList)
                contract.updateViewContent()
            }

            override fun onCancelled(databaseError: DatabaseError) {
                Log.d("some", "Error trying to get targets for ${databaseError.message}")
            }
        }
        targetsRef?.addListenerForSingleValueEvent(valueEventListener)
    }

    fun getTargetsByDeadline() {
        val valueEventListener = object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                targetList.clear()
                dataSnapshot.children
                    .mapNotNull { it.getValue(Goal::class.java) }
                    .sortedBy { it.deadline }
                    .toCollection(targetList)
                contract.updateViewContent()
            }

            override fun onCancelled(databaseError: DatabaseError) {
                Log.d("some", "Error trying to get targets for ${databaseError.message}")
            }
        }
        targetsRef?.addListenerForSingleValueEvent(valueEventListener)
    }
}

标签: androidfirebasekotlinfirebase-realtime-database

解决方案


优化是描述问题的错误词。问题是重复相同的代码(违反 DRY 原则),这可能是一个问题,因为如果您需要更改某些内容,它会引发错误,而且可读性较差。

在这种情况下,它并不极端,但我想它可以有所改进。你可以声明一个监听器的类实现,它接受一个参数来对列表进行排序。

class TargetsPresenter(private val contract: SelectTargetViewContract) {

    //...

    fun getTargetsFromDb() {
        targetsRef?.addListenerForSingleValueEvent(MyValueEventListener<String>())
    }

    fun getTargetsByPriority() {
        targetsRef?.addListenerForSingleValueEvent(MyValueEventListener(Goal::priority))
    }

    fun getTargetsByDeadline() {
        targetsRef?.addListenerForSingleValueEvent(MyValueEventListener(Goal::deadline))
    }

    private inner class MyValueEventListener<R: Comparable<R>>(
        private val sortCriteria: (Goal) -> R? = { null }
    ) : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            targetList.clear()
            dataSnapshot.children
                .mapNotNull { it.getValue(Goal::class.java) }
                .sortedBy(sortCriteria)
                .toCollection(targetList)
            contract.updateViewContent()
        }

        override fun onCancelled(databaseError: DatabaseError) {
            Log.d("some", "Error trying to get targets for ${databaseError.message}")
        }
    }
}

推荐阅读