0

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();
    }
}
  • Which Factory type this code is? and is it a proper writing of factory methods?
  • The factory pattern definition is: create an object without exposing the creation logic to the client

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);
}
WarrenFaith
  • 57,492
  • 25
  • 134
  • 150
Nimrod
  • 1,100
  • 1
  • 11
  • 27
  • Can we see the inner workings of the 3 fruit classes? – Bálint Jul 11 '16 at 14:13
  • see [Design Patterns: Abstract Factory vs Factory Method](http://stackoverflow.com/questions/4209791/design-patterns-abstract-factory-vs-factory-method) – jan.supol Jul 11 '16 at 14:38

3 Answers3

1
  • 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

wake-0
  • 3,918
  • 5
  • 28
  • 45
1

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.

Bálint
  • 4,009
  • 2
  • 16
  • 27
  • You are taking the tree analogy too far -- objects most often need parameters to be created, regardless how you create them. A factory is neither meant nor should eliminate the need for object construction parameters. Your analogy could perhaps be described as beautiful in a sense, if it were not for the fact that a factory creates objects for its clients, whereas a real tree creates fruit for no specific purpose, hence no parameters. Also number of parameters is completely orthogonal in the decision to use the factory pattern. – Armen Michaeli Jul 11 '16 at 16:46
  • @amn Putting a layer of abstraction on top of something doesn't mean it completely eliminates the need for arguments. It simply means it enters some of them automatically. – Bálint Jul 11 '16 at 17:12
  • I didn't say it eliminates arguments or should, in fact I said it doesn't and shouldn't. Whether it enters some of them automatically does not make it a factory. A layer of abstraction where *creation details* are encapsulated **does** make it a factory. I never said all abstractions are factories. Neither have you for that matter, but you do imply in your second paragraph that it there is no need for factories if object has enough information to create itself -- that is simply untrue. The last paragraph also does not have anything to do with factories, as I explained in my first comment. – Armen Michaeli Jul 11 '16 at 17:51
0

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.

Armen Michaeli
  • 8,625
  • 8
  • 58
  • 95
  • Your second statement in the 4th paragraph ("A fruit factory where you can specify the concrete class of fruit you want, still matches a valid factory pattern.") is incorrect based on the original definition: ""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."" – Bálint Jul 11 '16 at 19:20
  • You are right -- according to the original definition my statement is simply wrong. I do think that object pools are often implemented through no little inspiration of factory pattern, and there you often need to specify the kind of object you want explicitly. Regardless, I don't think my answer is as useless as its current score indicates and to think that I was the person who upvoted both of the other answers here :) – Armen Michaeli Jul 11 '16 at 19:48