Actually I'm reading again the excelent Effective Java book from Joshua Bloch. This book was very important for my Java learning in the past, with lots of good pratices to follow. Actually I'm reading it again with Android in mind. Since the book is about the Java Language, almost everything keeps up-to-date. But the interesting part is how to apply ideas or how they are actually already applied in Android development.
The first topics covered in the book are related to object creation. I want to explore the first topic of the book, static factory methods both on Android components already defined as using the concept with our own code.
Static Factory Methods
In order to create a new object, we usually use the class constructor to receive a new instance of that class. This is the default behavior of object creation in Java. You can receive paramenters and do something inside the constructor to create the object with some pre-defined values.
This works pretty well. However, we have another way to instanciate new objects with a different idea in mind. We could create objects with a method responsible for that, so we could give it a more meaningful name. Also, we could manage if the object being created really needs to be a new instance. Or return an instance different from that class, even if this sounds weird in the first place.
Some Android componets use this exactly behavior. Toast messages (that will be soon replaced by Snackbar) are good examples.
When you call a Tost component you don't need to instanciate directly. What you do is a call to a static factory method, the makeText method. You will pass some parameters so android can fabricate the Toas message in a good way.
You can see more implementation details here.
Creating Fragments with static factory methods
We will first learn Android you understand that an Activity is a core part of the framework. Soon, you realize that using Fragments is also a good pratice, cause you can reuse the behavior and decouple code. So, to create a Fragment passing a text for example, you should do something like this.
There is nothing really wrong with this code, but we could do it better. Using a static factory method we can provide three critical improvements here.
First, a static factory method inside TextFragment can reduces code by subsequently increasing code readability.
Second, a static factory method can ensures the same key is used to add parameters to the Bundle. Having multiple parameters would only increases the potential to accidentally mix up keys and their accompanying parameters, and it will be Activity's responsabilite to correclty manage this.
Finally, the static factory method helps prevent mundane code errors such as forgetting to call setArguments(). In this respect, reusing the same code to instantiate a Fragment may significantly reduce the time it takes to debug such issues.
With the static factory method in place, we can now initialize the TextFragment with the following code:
Using a static factory method can bring some advantages to the design of your code. Below we have listed some Advantages and Disadvantages of this approach:
- You can control the name and thus give it much more meaningful names
- You are not required to create a “new” object each time they are invoked
- You can even return an object that’s a subtype of the return type (unlike constructors which only return class type)
- Classes without public or protected constructors cannot be subclassed
- Static factory methods are not readily distinguishable from other static methods