Extension Functions vs Static Utility Class
While working in Android, there are quite a few times when we create a Util file or Extension functions to reuse the same set of code again and again.
In this blog, we are going to talk about when to use extension function and when to use static utility class in the android project using kotlin.
We will break the blog into,
- What are Extension function and Util Class?
- Use Cases where we use them?
- Advantages of using Wrapper like Extension or Util Class.
So, let's begin the blog.
What are Extension function and Util class?
Extension function : These are like extensive property attached to any class in kotlin. It provides additional methods to that class without manually inheriting the class.
For example,
Let's say, we have views where we need to play with the visibility of the views. So, we can create extension function for views like,
fun View.show() {
this.visibility = View.VISIBLE
}
fun View.hide() {
this.visibility = View.GONE
}
and to use it we use, like,
toolbar.hide()
Here, you can see we have attached an additional feature of hide() and show() to views in android.
Here, these above two extension functions can only be used by View Type and not any other type. For example, String can't use the functions here.
And to access, that view in the function we use this.
Util Class:
Util class is like a collection of static functions whose code can be reused again and again by passing the reference of the type as a parameter.
For example, if we take the above example of visibility Gone and Visible then update the code according to Util class way,
object Util {
fun show(view: View){
view.visibility = View.VISIBLE
}
fun hide(view: View){
view.visibility = View.GONE
}
}
and to use it we use,
Util.show(imageView)
Here, you can see unlike extension function, we need to pass the reference of the view as a parameter.
Or we can directly write the util functions without Util object. For example, we will create a file
Util.kt
and update the file as,
fun show(view: View){
view.visibility = View.VISIBLE
}
fun hide(view: View){
view.visibility = View.GONE
}
and to use this we can directly call,
show(imageView)
We can create Util both ways mentioned above.
Use Cases where we use them?
Now, in this section let us discuss when and where to use them.
Consider this like, when creating an extension function in kotlin, it creates a property for that specific type(let's say ImageView) which can be accessed across by all the ImageViews.
But, when Using Util, we don't add this property again, and again to use the util functions, we need to explicitly call it.
So, now let's understand this with an example.
Consider we have an ImageView, where we want to load image from url. We might consider using Glide or Picasso for this. So, here I will use Glide and create an extension function like
fun ImageView.loadImage(url: String) {
Glide.with(this.context).load(url).into(this)
}
Here, you can see I created an extension function called loadImage() which takes url as a parameter and we load the url into the ImageView.
Now, to use this we just use,
imageViewProfile.loadImage("url")
This loadImage property is accessed by the imageViewProfile and here the extension function is helping the ImageView to load the image from url.
Now, think this as this won't be just accessible for
imageViewProfile
but for all the ImageViews in the app but will only be accesible by ImageViews.
loadImage()
has become like property to ImageViews now. All the ImageViews can access it but just using the dot operator.
Now, Consider the same example using Util class. Here you need to pass both them imageView and the url to load the image.
fun loadImage(imgView:ImageView,url:String){
Glide.with(this.context).load(url).into(imgView)
}
and to use this we have to call
Util.loadImage()
.
Now, here it is not associated with imageView. We are passing the ImageView as a parameter to this function along with the url to load the url in the image view.
When to use Extension function or Util function?
Let's say if we have a multiple occurrence of the same action across the app like loading image from url in ImageView in multiple ImageViews across the app, we should prefer using extension function as it is like the major use-case here and so it gets attached to the imageView as a property.
But, when we don't want to use the property heavily and its a very rare occurrence in the app like once or twice we should use util functions.
Advantages of using Wrapper like Extension or Util Class.
In any case, using either extension functions or util class helps us a lot while developing the android app. It helps us,
- to make the code reusable.
- to make the code more readable.
- to migrate to another library very easily.
Let me explain them one by one.
Let's say in the above example,
fun ImageView.loadImage(url: String) {
Glide.with(this.context).load(url).into(this)
}
Here, the loading of image using glide is written once and can be used multiple times.
Using the loadImage() as the name makes our code readable as when we use it like,
imageViewProfile.loadImage("url")
the name itself makes it more clear that we are trying to load an url to the ImageView.
And at last, the biggest advantage of using a wrapper helps us in migration to another library if required . For example, let's say someday we need to remove the Glide library and replace the code with Picasso to load images.
Then we need to only update the code only once in either extension function or the util class and the library would be replaced successfully. We would not have to change or tweak any code in view files.
Conclusion :
Depending upon the use-case we should decide which way to use to make our code reusable.
Happy learning.
Team MindOrks :)