Factory Method

GoF definition (p. 107):

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

Pros:

  • Allows for more flexible, subclass-specific methods of object creation.
  • The abstract factory method defines a clear interface the enforces certain requirements on subclasses factory methods.

Cons:

  • Can require creation of new subclasses to implement minor differences in object creation.

Examples

Ruby

Abstract class

class Package
  class << self
    STANDARD_RATE = 1.50
    EXPRESS_RATE = 3.50

    def prepare_standard(weight) # A factory method
      postage = weight * STANDARD_RATE
      new(postage) # Class of instance is deferred to subclasses
    end

    def prepare_express(weight) # Another factory method
      postage = weight * EXPRESS_RATE
      new(postage)
    end

    # make 'new' private so Packages must be instantiated with factory methods
    private :new
  end

  attr_reader :postage

  def initialize(postage)
    @postage = postage
  end
end

Concrete class

class HazardousPackage < Package
  class << self
    STANDARD_RATE = 3.00
    EXPRESS_RATE = 7.00

    # Factory methods are inherited, and since they did not specify
    # the instantiated class of Package, they can be used without
    # further modification.
  end
end

Since we made new private, this would throw an error HazardousPackage.new(5)

standard_ebola_sample = HazardousPackage.prepare_standard(5)
puts standard_ebola_sample.postage

express_ebola_sample = HazardousPackage.prepare_express(5)
puts express_ebola_sample.postage

PHP

<?php
class Automobile
{
    private $vehicleMake;
    private $vehicleModel;

    public function __construct($make, $model)
    {
        $this->vehicleMake = $make;
        $this->vehicleModel = $model;
    }

    public function getMakeAndModel()
    {
        return $this->vehicleMake . ' ' . $this->vehicleModel;
    }
}

class AutomobileFactory
{
    public static function create($make, $model)
    {
        return new Automobile($make, $model);
    }
}

// have the factory create the Automobile object
$veyron = AutomobileFactory::create('Bugatti', 'Veyron');

print_r($veyron->getMakeAndModel()); // outputs "Bugatti Veyron"

References

results matching ""

    No results matching ""