Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

public static factory method

Tags:

First of all please forgive me if its a really dumb question, I am just trying to learn this language to its core. I am reading Effective Java and the very first chapter talks about Static factory methods vs. Constructors. Their pros and cons. Few things that are confusing to me are:

  1. class of an object returned by static factory method is nonpublic - what exactly does it mean?
  2. unlike constructors static factory methods are not required to create a new object each time they are invoked - How does this happen? I am invoking factory method only to obtain a new object and do we put a check in factory method for checking if object already exists?

Thanks.

like image 835
t0mcat Avatar asked Nov 02 '10 15:11

t0mcat


People also ask

What is a static factory method?

A static factory method is a public static method on the object that returns a new instance of the object. These type of methods share the same benefits as the traditional factory method design pattern. This is especially useful for value objects that don't have a separate interface and implementation class.

Which are the three types of factory method?

the abstract factory pattern,the static factory method, the simple factory (also called factory).

Is factory method always static?

A factory method is nothing but a static method that returns an object of the class. The most common example of a factory method is getInstance() method of any Singleton class, which many of you have already used.

Why are factory methods static?

Static factory methods can encapsulate all the logic required for pre-constructing fully initialized instances, so they can be used for moving this additional logic out of constructors. This prevents constructors from performing further tasks, others than just initializing fields.


2 Answers

class of an object returned by static factory method is nonpublic - what exactly does it mean?

It means that the actual class of the objects returned by a static factory method can be a subclass of the declared type, and this subclass does not have to be public. It's just another implementation detail that client code should not care about.

unlike constructors static factory methods are not required to create a new object each > time they are invoked - How does this happen? I am invoking factory method only to obtain a new object and do we put a check in factory method for checking if object already exists?

Yes, that's one way this could be done. But really, anything is possible.

like image 131
Michael Borgwardt Avatar answered Oct 06 '22 00:10

Michael Borgwardt


First off, kudos to you for your choice in Java-lit: Bloch's book is an excellent primer.

To answer your 2nd question ('unlike constructors static factory methods are not required to create a new object each time they are invoked'), it's important to realize that what Bloch is saying here is that with a static factory you have the option of either: returning a new object or returning a pre-existing one. It all depends on what you want to do.

For example, let's suppose you have a really simple value class of type Money. Your static factory method probably should return a new instance -- that is, a new object with a specific value for Money. So, like this:

public class Money { 

    private Money(String amount) { ... } /* Note the 'private'-constructor */

    public static Money newInstance(String amount) {
        return new Money(amount);
    }

}

But let's say you have some object that manages some resource and you want to synchronize access to that resource through some ResourceManager class. In that case you probably want your static factory method to return the same instance of itself to everyone -- forcing everyone to go through that same instance, so that that 1 instance can control the process. This follows the singleton-pattern. Something like this:

public ResourceManager {

    private final static ResourceManager me = new ResourceManager();

    private ResourceManager() { ... } /* Note the 'private'-constructor */

    public static ResourceManager getSingleton() {
        return ResourceManager.me;
    }
}

The above method forces your user to only ever be able to use a single instance, allowing you to precisely control who(and when) has access to whatever it is you are managing.


To answer your first question, consider this (admittedly not the best example, it's pretty ad-hoc):

public class Money {

    private Money(String amount) { ... }


    public static Money getLocalizedMoney( MoneyType localizedMoneyType, String amount ) { 
        switch( localizedMoneyType ) {
            case MoneyType.US:
                return new Money_US( amount );
            case MoneyType.BR:
                return new Money_BR( amount );
            default:
                return new Money_US( amount );
        }
    }
}

public class Money_US extends Money { ... }

public class Money_BR extends Money { ... }

Note how I can now do this:

Money money = Money.getLocalizedMoney( user_selected_money_type );
saveLocalizedMoney( money );

Again, a really contrived-example but hopefully it helps you see more or less what Bloch was getting at with that point.

The other answers were good -- I just think that, as a beginner, sometimes it helps to see some actual code.

like image 45
Bane Avatar answered Oct 06 '22 01:10

Bane