Pergunta

I am currently studying design patterns from the book (which, although I didn't try anything else, I find excellent) Head First Design Patterns.

I'm confused about two concepts: The Factory Method, and the Factory Method Design Pattern.

I was trying to understand what each one means, and I came to some conclusion. I'd like to know if my definitions are exact.


The Factory Method is a method that is meant to do one thing: Create an object of a specific supertype and return it. It may or may not take a parameter, and may or may not 'decide' using if statements what kind of concrete object to create.

For example, this is a factory method:

public Hat createHat(String hatColor){

    Hat hat;

    if (hatColor.equals("red")) hat = new RedHat();
    else if (hatColor.equals("blue")) hat = new BlueHat();
    else if (hatColor.equals("green")) hat = new GreenHat();
    else hat = new DefaultHat();

    return hat;

}

The Factory Method Design Pattern is named after the Factory Method.

This pattern provides a specific way to encapsulate object creation from the client.

It works like so: The pattern is a system of two classes, the Creator and the ConcreteCreator. The Creator is an abstract class, and the ConcreteCreator is a subclass of that class.

The job of the ConcreteCreator - create an object and return it using a factory method. It only has to contain this one method.

The job of the Creator - manipulate and use the object received from it's subclass, the ConcreteCreator, and usually return it to the client.

It is done like so:

The Creator contains an abstract method, it's signature something like SupertypeObject createObject(). Whenever it needs an object of type SupertypeObject, it calls createObject().

Thing is, createObject() is as I said abstract. It's the ConcreteCreator's job to implement this method.

This way, the implementation of createObject() is hidden from the Creator. It doesn't know what concrete object it gets, but it knows for sure that it's of type SypertypeObject.

This way, a client can use the Creator object to create objects of some supertype, but the concrete objects created will depend on the subclass. Thus declaring ShoeFactory factory = new CaliforniaStyleShoesFactory(), will make the factory produce california style shoes, while ShoeFactory factory = new NYStyleShoesFactory() will make the factory produce NY style shoes. Since the implementation of creating the concrete objects depends on the ConcreteCreator.

Code to demonstrate:

Class Client(){

    public static void main(String[] args){

        ShoeFactory factory;
        Shoe shoe;

        factory = new NYStyleShoeFactory();
        shoe = factory.makeShoe();
        System.out.println(shoe.getDescription()); // "A NY style shoe".

        // ShoeFactory's makeShoe() invokes createShoe() in the subclass, receives a Shoe
        // (doesn't know the concrete type of the Shoe. Depends on the subclass) and
        // does manipulations on it.
        // Returns the Shoe to the client.

        factory = new CaliforniaStyleShoeFactory():
        shoe = factory.makeShoe();
        System.out.println(shoe.getDescription()); // "A California style shoe".

}

}

Is my understanding of the two concepts accurate? Thanks

Foi útil?

Solução

Yes, you are right.

The pattern is called like that because it describes a known, well accepted solution using a factory method.

The pattern could have been named "XXXX". That doesn't matter.

Regarding @pdr's comment about what you describe being really an "Abstract Factory", the following images clarify the difference, Factory Method is exactly what you describe:

enter image description here

enter image description here

The images are taken from this PDF taken from this site. It was maded by a software engineer by the name of Jason McDonald.

Outras dicas

You said something in a comment that bears highlighting and explanation.

How can one method be a pattern?

While most design patterns are templates of classes or objects and how they all relate to each other, that's really only true of object oriented design patterns. The topic of design patterns has applicability far beyond that, and there are some design patterns, like factory or interface, that apply very well to implementations using a single method or function.

For example, we can use both in a simple functional JavaScript program. Let's say we have something like what follows, to call an ActiveX object our company uses on an Intranet.

var oNeat = new ActiveXObject("OurCompany.NeatThing");
oNeat.DoStuff();

Seems simple, except we can wrap both lines above in a pair of respective pattens.

function GetNeatThing() {
  return new ActiveXObject("OurCompany.NeatThing");
}

function DoStuff(onWhat) {
  if(onWhat && onWhat.DoStuff) {
    onWhat.DoStuff();
  }
}

and then our call becomes simply:

var oNeat = GetNeatThing();
DoStuff(oNeat);

While this doesn't get us a lot by itself, we do get significantly better modularity. If we move the GetNeatThing and DoStuff functions into their own js file, and use them instead of the hard-coded references, we wind up with all of the benefits of having a Factory and an Interface.

(Specifically, we could change the progID of our NeatThing, or even move it away from ActiveX to something like a web server. And we could even change how it works, by re-naming the atrocious "DoStuff" method to something more descriptive, while not breaking existing code.)

Licenciado em: CC-BY-SA com atribuição
scroll top