Search code examples
kotlinstrategy-pattern

Split algorithm and view part using a Strategy Pattern in Kotlin


This is the code I would like to refactor:

val postListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
            // Get Post object and use the values to update the UI
            requestsUsers?.clear()
            val match = dataSnapshot.children
            val keysArray = KeysHandler()
            if (match != null) {

                for (data in match) {
                    keysArray.addToList(data.key)
                }
                if (keysArray.list.size > 0) {
                    repeat(keysArray.list.size) { i ->
                        val onlineMatch = dataSnapshot.child(keysArray.getElement(i)).getValue(OnlineMatch::class.java)!!
                        onlineMatch.key = keysArray.list[i]
                        requestsUsers.add(onlineMatch)
                    }
                }
            }
            //Updating GUI
            updateRequests()

}

As you can see I am downloading data in an array called match. Then I parse the same array obtaining an array of keys (keysArray). Then I add a specific element of the keys array to another array (requestsUser).

Considering that this algorithm could be changed I would like to incapsulate the algorithm part in another class. I read somewhere that in these kind of situation the best thing to do is to use a Strategy Pattern, but I am working in kotlin. How could I implement a Strategy Pattern in Kotlin?


Solution

  • It should be similar to Java.

    Suppose the type of requestsUsers is ArrayList<RequestsUser>.

    Create the strategy interface.

    interface Strategy {
        fun getRequestsUsers(dataSnapshot: DataSnapshot): ArrayList<RequestsUser>
    }
    

    Implement the interface.

    class StrategyImpl: Strategy {
    
        override fun getRequestsUsers(dataSnapshot: DataSnapshot): ArrayList<RequestsUser> {
            val match = dataSnapshot.children
            val keysArray = KeysHandler()
            val requestsUsers = arrayListOf<RequestsUser>()
            if (match != null) {
    
                for (data in match) {
                    keysArray.addToList(data.key)
                }
                if (keysArray.list.size > 0) {  //this line can be omitted
                    repeat(keysArray.list.size) { i ->
                        val onlineMatch = dataSnapshot.child(keysArray.getElement(i)).getValue(OnlineMatch::class.java)!!
                        onlineMatch.key = keysArray.list[i]
                        requestsUsers.add(onlineMatch)
                    }
                }
            }
            return requestsUsers
        }
    }
    

    Declare the strategy in your class

    var strategy = StrategyImpl()  //make it var so that it can be changed
    

    Finally, use strategy to get the list of data and add to the list.

    val postListener = object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            // Get Post object and use the values to update the UI
            requestsUsers?.clear()
            requestsUsers?.addAll(strategy.getRequestsUsers(dataSnapshot))
            //Updating GUI
            updateRequests()
        }
    }