Factory Method (aka. Virtual Constructor) defines an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

Structure

Class diagram (UML):

Factory Method Class Diagram (UML)

When Would You Use It?

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

Related Patterns

Design PatternNotes
Abstract FactoryIt is often implemented with factory methods.
Template MethodsFactory methods are usually called within Template Methods.
PrototypesPrototypes don’t require subclassing Creator. However, they often require an Initialize operation on the Product class.

Discussion

Factory Method vs. Abstrct Factory

The Abstract Factory and Factory Method patterns are very similar in many ways. It’s very confusing to many people when to use which one of them. Both of them can be used for the same purposes of creating objects without letting clients know what exact concrete objects are being returned.

|Factory Method|Abstrct Factory|
|–|–|
|Abstract product creation through class inheritance.|Abstract product creation through object
composition
.|
|Creates one type of product.|Creates families of products.|
|Subclass the Creator and override the factory
method to create new products.|The parent interface needs to be changed for
supporting new products.|

References

  • Design Patterns: Elements of Reusable Object-Oriented Software, by Book by Erich Gamma, John Vlissides, Ralph Johnson, and Richard Helm (GoF)
  • Pro Objective-C Design Patterns for iOS, by Carlo Chung
  • Pro Design Patterns in Swift, by Adam Freeman

Example #1 – Apple Products

Assume Apple has the following product lines: iPhone, iPad. We create the factory method for each of the products.

Here is the class diagram:

Factory Method Class Diagram (UML) - Apple Products

Code

import Foundation
import UIKit

// Protocol for "Product" 
protocol AppleProduct {

    var name: String {get set}
    var screenSize: Double {get set}
    var price: Double {get set}

    func getProduct() -> String
}

// Protocl for "Creator" 
protocol AppleProductCreator {

    func createProduct() -> AppleProduct
}

// Class for "ConcreteProduct"
class IPhoneProduct: AppleProduct {

    var name: String = "iPhone 6"
    var screenSize: Double = 4.7
    var price: Double = 199.00

    func getProduct() -> String {

        return "Apple product "(name)", with screen size in (screenSize) inch, at proce: $(price)"
    }
}

class IPadProduct: AppleProduct {

    var name: String = "iPad Air 3"
    var screenSize: Double = 10.1
    var price: Double = 499.00

    func getProduct() -> String {

        return "Apple product "(name)", with screen size in (screenSize) inch, at proce: $(price)"
    }
}

// Class for "ConcreteCreator"
class IPhoneProductCreator: AppleProductCreator {

    static let sharedInstance:IPhoneProductCreator = IPhoneProductCreator()

    func createProduct() -> AppleProduct {

        return IPhoneProduct()
    }
}

class IPadProductCreator: AppleProductCreator {

    static let sharedInstance:IPadProductCreator = IPadProductCreator()

    func createProduct() -> AppleProduct {

        return IPadProduct()
    }
}

// Client Usage
let product1: AppleProduct = IPhoneProductCreator.sharedInstance.createProduct()
println("Got a new device: " + product1.getProduct())

let product2: AppleProduct = IPadProductCreator.sharedInstance.createProduct()
println("Got a new device: " + product2.getProduct())

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>