Search code examples
kotlinandroid-recyclerviewlistadapterandroid-diffutils

DiffUtil.ItemCallback - define as a companion object or as a class?


I'm currently learning Kotlin through the Kotlin Android Developer program from Udacity. There's two sample apps using DiffUtil.ItemCallback, but declare it in different ways. Both sample apps use a ListAdapter, however one declares the DiffUtil like this: companion object DiffCallback : DiffUtil.ItemCallback<MarsProperty>()

while the other like this: class SleepNightDiffCallback: DiffUtil.ItemCallback<SleepNight>()

Both DiffUtils are passed as parameters to the ListAdapter, with the only difference being that in the case of the class implementation, it has to be initialised:

class PhotoGridAdapter : ListAdapter<MarsProperty, PhotoGridAdapter.ViewHolder>(DiffCallback)
class SleepNightAdapter : ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback())

The only difference between those sample apps is that one downloads and shows images from the internet (the one with the PhotoGridAdapter), while the other shows data from a database, so my question is: Is one implementation preferred compared to the other? Are there any performance differences between them?


Solution

  • This is probably a matter of opinion. Mine is that the callback should be an object, or anonymous object, but not a companion object.

    All it's doing is comparing properties of two objects. It doesn't have to hold any state. So it makes sense for it to be a singleton object rather than a class that you have to instantiate. Whether you define it as a named singleton object or define in place as an anonymous object assigned to a property doesn't make much different in communicating intent.

    But it doesn't make sense to me to make it a companion. It's already nested and has a name. All companion does is suggest that you should need to call its functions directly and that the name PhotoGridAdapter should also be thought of as a callback. For instance, it enables you to pass the name PhotoGridAdapter to some other adapter as its DiffUtil callback, which is nonsensical. The only reason it might possibly make sense is if you also want to use it as a utility for comparing items, so you could call functions like PhotoGridAdapter.areContentsTheSame directly. However, I don't think this is likely. Usually, the contents of the callback's functions are either very trivial like passing through equals() or they are very specific to the nature of updating the displayed list.