Nimrod
Nimrod

Reputation: 1140

Is this code implements 'Factory Pattern', factory methods, both or none?

Although this subject has been discussed many times, I still find myself get too confused with it.

I have this simple code sample:

public class FruitFactory {

    public static Apple getApple() {
        return new Apple();
    }

    public static Banana getBanana() {
        return new Banana();
    }

    public static Orange getOrange() {
        return new Orange();
    }
}

If I expose my client to some of the creation complexity like as the example below, is it a bad factory implementation?

public static Orange getOrange(String weight, String size,) {
    return new Orange(weight, size);
}

Upvotes: 0

Views: 198

Answers (3)

Bálint
Bálint

Reputation: 4049

The factory pattern's purpose is to put an abstraction layer on top of object creation.

If the object has enough information to create itself without too many arguments or settings, then you don't need to use a factory pattern, as the object's constructor is a factory in itself.

This is the problem with your current code, it doesn't add a layer of abstraction to anything. You simply encapsulate the constructor.

The problem with the second code sample is the same, if it were a factory, then it would choose the weight or size of the fruits randomly or by an algorithm, like a real tree does.

Edit: The original Gang of four description is

"Define an interface for creating an object, but let subclasses decide which class to instantiate. The Factory method lets a class defer instantiation it uses to subclasses."

This means, that your code isn't a factory, because you need to define what you need.

Upvotes: 1

Armen Michaeli
Armen Michaeli

Reputation: 9150

As it is said, a factory is merely an abstraction where object creation implementation is intentionally encapsulated behind the factory's public interface. A factory does not have to be a class, it does not have to be a package -- different languages achieve encapsulation of state and behavioral details differently (consider closures, for instance).

A function in a language that allows "top-level" functions, can be a factory as well:

public Orange growNewOrange(String weight, String size) {
    /// ...traditionally not callers concern.
}

If the factory hides creation code behind a way for you to use it without concerning yourself with said creation code for each created object, you already have a useful isolation (between getting new objects and that which manages them) that solves the problem the factory pattern was designed to solve.

There are factories that are designed to create and manage one kind of objects and then there are those that create and manage multiple kinds of objects. A fruit factory where you can specify the concrete class of fruit you want, still matches a valid factory pattern.

Categorizing factory implementations into "types" is done by various OOP authors, and may be useful for various good reasons, but this is not essential to be able to utilize the general idea to your advantage.

The immediately useful advice would be encapsulate creation code in a Java package or class, where specifying parameters of a created object is done on a per-object basis, while factory state controlling creation logic -- for instance size of reused object pool etc -- is set up during factory creation itself. Object pools are one of the examples of factory pattern at work.

Upvotes: 0

wake-0
wake-0

Reputation: 3966

  • The first code is a Factory pattern because you have just one class without subclassing, overriding, etc.

When you want to use a factory method than write (Banana inherits from Fruit):

public abstract FruitFactory {
    public abstract Fruit createFruit();
}

public BananaFactory extends FruitFactory {
    @Override
    public Fruit createFruit() {
        return new Banana();
    }
}

The implementation:

public static Orange getOrange(String weight, String size) {
    return new Orange(weight, size);
}

is also a correct implementation in my opinion because you encapsulate the creational logic like explained from @amn.

The good thing in using the static method is that you can make the constructor private so it is only possible to instantiate objects by using the method.

For better understanding see the following link: patterns

Upvotes: 1

Related Questions