Consider static factory method
How should we create an object? What are the cons and pros by using public constructor? How can you make sure that you have the correct object?
One of the basic problems in android is holding the key of pair. Since bundle requires key/value pair, you always need to have a key. Problem is where to holds these keys?
Assume that we want to send some data from LoginActivity to HomeActivity :
There are a few approaches.
Each activity creates the same keys.
Cons: Duplication and it is easy to make typo.
Make the keys public in one class and access it everywhere
Cons: This will create a coupling and the class has to know which keys to call all the time. This can also affect the system. Assume that you used another key by mistake.
Put all keys in one utility class
Cons: I think this is the worst of first two. All classes will be coupled with this class and one small mistake will affect the whole system. After a while with a lot of keys, it will be out of control easily.
Well, what to use then?
Static factory method helps a lot in these cases.
Instead of creating the object of another class, let the corresponding class to create the object.
HomeActivity itself is the responsible of creating its own intent.
The caller class doesn’t need to know anything about this creation nor keys. LoginActivity will just tell the HomeActivity, “hey, I need an intent with this data”. That’s all. HomeActivity will do everything else.
The same rule applies for fragments too.
As we know that you should not use non-default constructor to pass the data, the main reason is when the fragment is recreated in cases such as config changes or rotation, default constructor will be used and you will lose your data. You need to work around to fix it.
With the static factory method, you can have a neat solution and avoid this issue. Create a method to pass your variables and put them into a bundle and set it to fragment.
Static factory method is also very useful in null conditions.
For example; we had to copy an object to another and some fields could have been null.
If the response.userResponse is null, it will throw a null pointer exception because of the User constructor.
User class always expects non-null object.
One solution is to make a null check in Account class before creating the object.
This makes the code a little ugly and unreadable. Imagine that you have a lot of this situation and you basically need to check null all the time.
The other solution could be to do null check in User class.
But if you notice, the problem in here is we will get a new object which all fields are null. This will crash for sure in somewhere else.
The neat solution comes with the static factory method. We basically use the newUser method and first we check the response if the response is not valid we just return null without creating any object. If the response is valid, it will return a new user object.
You can also do other validations as well, such as one of the variable might be null and in this case you don’t want to create the object etc.
We heavily use static factory method and we take a lot of advantages from this approach.
- Clean/neat cod
- Loosely coupling
- The corresponding class could do a validation check before creating
- The corresponding class could use singleton pattern to return an existing object instead of creating.
- The corresponding class could create a subclass and return it.
In summary, the corresponding class has all power to do makes things right.