0

I'm studying about Design patterns. I have studied about Factory Design Pattern in java and i have Some things I didn't understand well and I'm writing them following.

  1. Is there any different between Factory Design Pattern and Factory Method Design Pattern.
  2. I saw in some examples, Factory class's get method is static and some examples its not static. What is the correct way.

Any help would appreciate.

Dehan Wjiesekara
  • 3,152
  • 3
  • 32
  • 46
  • For me this explanation was the best: http://stackoverflow.com/questions/13029261/design-patterns-factory-vs-factory-method-vs-abstract-factory – Andrei_N May 07 '16 at 12:05
  • A Factory is a class that is purposed to create objects and it may have one or many factory methods, but factory methods aren't exclusive to factory classes. The main reason to place a factory method on an object that isin't a factory is because this object has some knowledgte that will simplify the creation process. For instance, `twoMinutes = oneMinute.plusMinutes(1);` – plalx May 07 '16 at 15:49

3 Answers3

1

I'm not too deep in design patterns in the sense that I did not ingest massive books discussing them in much abstraction, but I certainly have an idea of what they are and know how to apply them. Here is my understanding of these two patterns:

  • Factory is a pattern that delays the instantiation of an object by handing an object that knows how to construct others objects.This can have several advantages going. For example, let's say you are writing a theading pool library. A pool contains objects that can perform certain actions, and you want to be able to create pools of any size. Each object of the pool must be a distinct object. You could ask the user of your pool to give you as many objects as they want in the pool, but you can also ask them for a single factory that you will use to instantiate the objects yourself. This way, you can also dynamically change the size of the pool, destructing or regenerating objects, etc... It gives all the flexibility you need without knowing anything about the objects your pool is holding.

  • Factory method is different. Let's say you have a big constructor with a lot of parameters. Some of these parameters may have default values, or you may have various way to configure this class. You could certainly add a constructor for each typical configuration (set of parameters) but this wouldn't be user-friendly as all the constructors share the same name. To make it easier, you could have static methods that just call the constructor with the appropriate configuration. The advantage is that you can name these methods (defaultHttpClientForProd, defaultHttpClientForDev etc...). Another use-case is if you have a massive class hierarchy, say an abstract class Car extended by dozens of classes. You could use each individual constructor to build your dream car, but you would have to look at each and every page of the catalog to decide which one you want. You could alternatively have a single page that summarizes all the cars available, this would be a class containing a lot of factory methods, making them more discoverable.

For your second question about, I would say it depends. If you don't need to customize your factory too much or inject a lot of context, a static method with some parameters will do the trick. If you want your factory to be more configurable, a class with attributes and an instance method will be better.

Dici
  • 25,226
  • 7
  • 41
  • 82
1

To be specific to your questions:

  1. Abstract Factory & Factory Method are two different design patterns. Refer to Gang of Four (Design patterns) for detailed explanation. The key difference is Abstract Factory or Factory is about creating families of related objects (note the word family meaning group of objects) whereas Factory Method is providing a creational method to create one particular type of object (not family), which can be implemented by multiple factory implementation class. Essentially, Factory Method is used in implementing Factory or Abstract Factory pattern but not the vice-versa.
  2. As far as static method is concerned, it is not mandated by the pattern itself. It is specific to Java & hence static modifier is used to make sure Factory's getInstance() or any creational method is Singleton. You don't want multiple instances of Factory and hence in Java, you implement by having static instance of Factory and therefore, you will need static method to return the static instance.
1

Different tutorials seem to mean different things by the factory design pattern. I would say that the ones in your links are both simple factories. I think this post explains the difference simply: Simple Factory vs. Factory Method vs. Abstract Factory

Simple factories can be identified by the use of a static method to create different subclasses, usually with some kind of if/else or switch structure. The example in the second link doesn't actually use a static method, but it can easily be made static without changing much.

In the Gang of Four book, the Factory Method Pattern is defined as:

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.

Because of the use of subclasses, static methods will not work here because they can't be overridden. The shape example done this way would be more like:

public interface ShapeFactory {
    Shape getShape();
}

public class CircleFactory implements ShapeFactory {
    public Shape getShape() {
        return new Circle();
    }
}

public class RectangleFactory implements ShapeFactory {
    public Shape getShape() {
        return new Rectangle();
    }
}

ShapeFactory shapeFactory = new CircleFactory();
...
Shape shape = shapeFactory.getShape();

Here, we can separate the creation of the factory from its usage. The factory can be created in one class and then passed to another, so a class can create different types of objects by being configured by another.

Or in Java 8, we can just use:

Supplier<Shape> shapeFactory = Circle::new;
...
Shape shape = shapeFactory.get();
fgb
  • 18,439
  • 2
  • 38
  • 52