In this video we're looking at static factories in Java.
Coming up next!
Imagine you're creating an class to represent coordinates.
The coordinates could be two numbers representing the x and y axis, or the two numbers can represent
a length and angle.
Think about that for a second.
This breaks because your constructor will only have two numbers for parameters, and
no way to guess which one you mean.
You could say integers for one, and floats for another but that's ugly and puts artificial
constraints on your class.
A constructor isn't going to work.
We could use a builder pattern, but it seems overkill for two parameters.
Lets look at a new pattern in Java called the static factory.
The static factory is a simple variation of the factory method pattern.
The factory method pattern is a design pattern we'll cover later.
The static factory method is simply a static method that returns an instance of a class.
It might call a constructor to create an instance, or it might return an instance it already
has created.
Our next thought is, how does this help us?
So back to our earlier problem, let's look at creating our coordinate class.
We could use a builder pattern here, but we've only got two parameters.
It's either x/y or length and angle.
Internally we'll store only one.
We'll go with x, y, for the only reason, we need to pick one.
You don't ever want two representations of the same thing.
You only want one truth in any system, and then convert to any other values.
So how do we create our coordinate instances?
Since we can't have two constructors with the same parameter lists, we'll create two
methods.
One is called fromXY() and the other fromPolar().
Both take two doubles and return a coordinate instance.
We'll ignore any calculation errors.
The polar method will convert to X/Y and then create the coordinate.
Our X/Y method just creates the coordinate.
Here's the rub.
How do we call these methods if we need an instance to call the method?
That's right.
Make the methods static.
That's why they are called static factories.
The other thing you'll want to do is make these methods final.
We don't want new behavior for creation here.
And finally we want to make the constructor private.
This enforces how instances in our class are created.
Ok.
Now that we have a static factory, how did this help us?
For starters, we now have more meaningful names to create our classes.
fromXY() and fromPolar() make it clear what values are going into the creation of our
instance.
That's easier to read than a constructor name.
We also have two ways to create our instances with the same parameter types.
Both methods take two double values, but the meaning of those values are different in each
case.
If we had constructors, these two instantiations are the same.
With static factory methods, it's clear how we're creating each instance and what the
parameters mean.
Another interesting advantage is conditional instantiation.
That means we don't have to create a new object if we don't want to.
Constructors must always return a new instance, even though the people at Java do break their
own rules in a few cases, but that's another story.
We talked about that in the tricky numbers video.
Anyways, if we're returning immutable objects, we might want to return the same one.
Say for example, we're using an integer coordinate system in a game that's only 10 x 10.
Each coordinate represents a single position in our game board that has only 100 positions.
It would be wasteful to keep creating instances for the same position.
We could keep a pool of coordinate instances, and when you call the static factory, we'll
just return the one already created.
Java does this with boolean values.
We might use the Boolean class in hundreds of places in an application, but there's only
two instances.
When you call valueOf("true"), you get the instance already created.
Sounds great!
Why not use static factories everywhere?
Well we've seen that these classes are final.
That means the class cannot be extended.
You could move the factory into another class.
This would allow you to create instances of subclasses, but I think a better plan is to
use something called interfaces.
We'll talk about those later.
The other problem is more of a readability issue.
You can't tell the difference between a method and a factory method.
They are syntactically equivalent.
The best practice is to use method names that indicates what you are doing.
Examples are instanceof(), valueof(), and so on.
So that's another way to create instance of your Java classes.
We've covered constructors, builder patterns, constructor chaining, and static factories.
Next we'll look at copy constructors.
Thanks for watching!
If you have any questions let me know in the comments.
New lessons come out every week, so make sure you subscribe.
You don’t want to miss a video!
Liking the video lets me know what I'm doing right, so if you liked the video...
And with that, I’ll see you in the next tutorial!