Martin Dvoracek
Martin Dvoracek

Reputation: 1738

Purpose of factory classes in Java

I have used Java for quite a long time, but I never did find out, what makes factories so special. Can somebody please explain it to me? Is there any reason why I should want to implement my own factory (if it's even possible)?

Upvotes: 6

Views: 4984

Answers (6)

Tel Bouqi
Tel Bouqi

Reputation: 164

Factory Patterns are fantastic for decoupling classes. For example, let's assume a common interface, Animal, and some classes that implement it. Dog, Cat.

If you do not know what the user will want to generate at run time, then you can not create a Dog pointer. It simply won't work!

What you can do though, is port that to a separate class, and at run time, pass a discriminator to the factory class. The class will then return the object. For example:

public Animal getInstance(String discriminator)
{
    if(discriminator.equals("Dog")) {
         return new Dog();
    }
    // etc.
}

And the calling class simply uses:

String type = "Dog";
Animal value = Factory.getInstance(type);

This makes code extremely readable, separates decision logic from the logic performed on the value and decouples the classes via some common interface. All in all, pretty nice pattern!

Upvotes: 14

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 135992

Factories are widely used in JDK to support the concept of SPI (service provider interface) - API intended to be implemented or extended by a third party. E.g. DocumentBuilderFactory.newInstance() uses a complicated 4-step search algorithm to find the actual implementation.

I think programmers who develop not libraries but applications should favour "simple is best" approach in software design.

Upvotes: 1

Alexis C.
Alexis C.

Reputation: 93842

Another good example can be the following. Imagine that the user want to uses somes collections to performs actions (in this case choose the collections to create an inverted index). You can create an interface like :

interface CollectionsFactory {
    <E> Set<E> newSet();
    <K, V> Map<K, V> newMap();
}

Then you could create a class which take a collections factory as parameter.

public class ConcreteInvertedIndex implements InvertedIndex {
    private final Map<String, Set<Document>> index;
    private final Set<Document> emptyDocSet;    
    private final CollectionsFactory c;

    public ConcreteInvertedIndex(CollectionsFactory c){
        this.c = c;
        this.index = c.newMap();
        this.emptyDocSet = c.newSet();
    }

//some methods
}

And finally it's to the user to decide which collections he wants to use to perform such actions :

CollectionsFactory c = new CollectionsFactory() {

            @Override
            public <E> Set<E> newSet() {
                return new HashSet<E>(); //or you can return a TreeSet per example
            }

            @Override
            public <K, V> Map<K, V> newMap() {
                return new TreeMap<K, V>();//or you can return an HashMap per example
            }
        };
        InvertedIndex ii = new ConcreteInvertedIndex(c);

Upvotes: 2

teckysols
teckysols

Reputation: 95

Use the Factory Method pattern when

· a class can't anticipate the class of objects it must create.

· a class wants its subclasses to specify the objects it creates.

· classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate.

Upvotes: 1

flavian
flavian

Reputation: 28511

IMO the biggest benefits of Factory classes are configuration and data encapsulation. API design is perhaps the most common scenario where such classes come in really handy.

By offering developers Factory classes instead of direct access, I have a way to easily preventing from someone messing up with the internals of my API, for instance. Through Factory classes I also control how much you know about my infrastructure. If I don't want to tell you everything about how I provide a service internally, I will give you a Factory class instead.

For reliability and uniform design purposes, the most crucial internals should be enclosed in Factory classes.

They are a way to make sure that a random developer that comes along will not:

  • Break internals
  • Gain unwanted privileges
  • Break configuration formats

Upvotes: 4

Igor Deruga
Igor Deruga

Reputation: 1546

You use them in combination with private constructor to create singletons. It assures that the bean (probably, a service) can not be created as a non-singleton.

You can also forbid the creation of the class with the constructor by making it private, so that you could add some logic in the factory method and nobody could bypass it.

EDIT: I know a person who would replace a constructor in every bean by a method "create" with parameters (in order to centralize the bean population logic), but I am not a big fan of this approach.

Upvotes: 0

Related Questions