0% found this document useful (0 votes)
74 views

Factory Pattern

The Factory pattern provides a generic interface for creating objects and allows clients to specify the type of object to be created. A Factory determines which class to instantiate, instantiates the object, and returns it to the client. This allows for more flexible object creation than directly instantiating objects with 'new'. The example shows a VehicleFactory that can create either Car or Truck objects depending on the options passed to its createVehicle method. An Abstract Factory groups related factories and provides a common interface for obtaining related objects.

Uploaded by

Minal Patil
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
74 views

Factory Pattern

The Factory pattern provides a generic interface for creating objects and allows clients to specify the type of object to be created. A Factory determines which class to instantiate, instantiates the object, and returns it to the client. This allows for more flexible object creation than directly instantiating objects with 'new'. The example shows a VehicleFactory that can create either Car or Truck objects depending on the options passed to its createVehicle method. An Abstract Factory groups related factories and provides a common interface for obtaining related objects.

Uploaded by

Minal Patil
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 5

The Factory Pattern

The Factory pattern is another creational pattern concerned with the notion of
creating objects. Where it differs from the other patterns in its category is that it
doesn't explicitly require us to use a constructor. Instead, a Factory can provide a
generic interface for creating objects, where we can specify the type of factory object
we wish to be created.

Imagine that we have a UI factory where we are asked to create a type of UI


component. Rather than creating this component directly using the new operator or
via another creational constructor, we ask a Factory object for a new component
instead. We inform the Factory what type of object is required (e.g "Button", "Panel")
and it instantiates this, returning it to us for use.
This is particularly useful if the object creation process is relatively complex, e.g. if it
strongly depends on dynamic factors or application configuration.

Examples of this pattern can be found in UI libraries such as ExtJS where the
methods for creating objects or components may be further subclassed.

The following is an example that builds upon our previous snippets using the
Constructor pattern logic to define cars. It demonstrates how a Vehicle Factory may
be implemented using the Factory pattern:
?
1 // Types.js - Constructors used behind the scenes
2
// A constructor for defining new cars
3 function Car( options ) {
4
5 // some defaults
6 this.doors = options.doors || 4;
7 this.state = options.state || "brand new";
this.color = options.color || "silver";
8
9 }
10
11 // A constructor for defining new trucks
12 function Truck( options){
13
this.state = options.state || "used";
14 this.wheelSize = options.wheelSize || "large";
15 this.color = options.color || "blue";
16 }
17
18
19 // FactoryExample.js
20
// Define a skeleton vehicle factory
21 function VehicleFactory() {}
22
23 // Define the prototypes and utilities for this factory
24
25 // Our default vehicleClass is Car
VehicleFactory.prototype.vehicleClass = Car;
26
27 // Our Factory method for creating new Vehicle instances
28 VehicleFactory.prototype.createVehicle = function ( options ) {
29
30 switch(options.vehicleType){
31 case "car":
this.vehicleClass = Car;
32 break;
33 case "truck":
34 this.vehicleClass = Truck;
break;
35 //defaults to VehicleFactory.prototype.vehicleClass (Car)
36 }
37
38 return new this.vehicleClass( options );
39
};
40
41 // Create an instance of our factory that makes cars
42 var carFactory = new VehicleFactory();
43 var car = carFactory.createVehicle( {
44 vehicleType: "car",
color: "yellow",
45 doors: 6 } );
46
47 // Test to confirm our car was created using the vehicleClass/prototype Car
48
49 // Outputs: true
console.log( car instanceof Car );
50
51 // Outputs: Car object of color "yellow", doors: 6 in a "brand new" state
52 console.log( car );
53
54
55
56
57
58
59
60
61
62
Approach #1: Modify a VehicleFactory instance to use the Truck class

?
var movingTruck = carFactory.createVehicle( {
1 vehicleType: "truck",
2 state: "like new",
3 color: "red",
wheelSize: "small" } );
4
5 // Test to confirm our truck was created with the vehicleClass/prototype Truck
6
7 // Outputs: true
console.log( movingTruck instanceof Truck );
8
9 // Outputs: Truck object of color "red", a "like new" state
10 // and a "small" wheelSize
11 console.log( movingTruck );
12
13
14
Approach #2: Subclass VehicleFactory to create a factory class that builds Trucks

?
1
2 function TruckFactory () {}
3 TruckFactory.prototype = new VehicleFactory();
4 TruckFactory.prototype.vehicleClass = Truck;
5
6 var truckFactory = new TruckFactory();
var myBigTruck = truckFactory.createVehicle( {
7 state: "omg..so bad.",
8 color: "pink",
9 wheelSize: "so big" } );
10
// Confirms that myBigTruck was created with the prototype Truck
11 // Outputs: true
12 console.log( myBigTruck instanceof Truck );
13
14 // Outputs: Truck object with the color "pink", wheelSize "so big"
15 // and state "omg. so bad"
console.log( myBigTruck );
16
17

When To Use The Factory Pattern


The Factory pattern can be especially useful when applied to the following
situations:

 When our object or component setup involves a high level of complexity


 When we need to easily generate different instances of objects depending on the
environment we are in
 When we're working with many small objects or components that share the same
properties
 When composing objects with instances of other objects that need only satisfy an
API contract (aka, duck typing) to work. This is useful for decoupling.
When Not To Use The Factory Pattern
When applied to the wrong type of problem, this pattern can introduce an
unnecessarily great deal of complexity to an application. Unless providing an
interface for object creation is a design goal for the library or framework we are
writing, I would suggest sticking to explicit constructors to avoid the unnecessary
overhead.

Due to the fact that the process of object creation is effectively abstracted behind an
interface, this can also introduce problems with unit testing depending on just how
complex this process might be.

Abstract Factories
It is also useful to be aware of the Abstract Factory pattern, which aims to
encapsulate a group of individual factories with a common goal. It separates the
details of implementation of a set of objects from their general usage.

An Abstract Factory should be used where a system must be independent from the
way the objects it creates are generated or it needs to work with multiple types of
objects.

An example which is both simple and easier to understand is a vehicle factory,


which defines ways to get or register vehicles types. The abstract factory can be
named abstractVehicleFactory. The Abstract factory will allow the definition of types
of vehicle like "car" or "truck" and concrete factories will implement only classes that
fulfill the vehicle contract (e.g Vehicle.prototype.drive and Vehicle.prototype.breakDown ).
?
var abstractVehicleFactory = (function () {
1
2 // Storage for our vehicle types
3 var types = {};
4
5 return {
getVehicle: function ( type, customizations ) {
6 var Vehicle = types[type];
7
8 return (Vehicle ? new Vehicle(customizations) : null);
9 },
10
11 registerVehicle: function ( type, Vehicle ) {
var proto = Vehicle.prototype;
12
13 // only register classes that fulfill the vehicle contract
14 if ( proto.drive && proto.breakDown ) {
15 types[type] = Vehicle;
}
16
17 return abstractVehicleFactory;
18 }
};
19 })();
20
21
22 // Usage:
23
24 abstractVehicleFactory.registerVehicle( "car", Car );
25 abstractVehicleFactory.registerVehicle( "truck", Truck );
26
// Instantiate a new car based on the abstract vehicle type
27 var car = abstractVehicleFactory.getVehicle( "car", {
28 color: "lime green",
29 state: "like new" } );
30
// Instantiate a new truck in a similar manner
31 var truck = abstractVehicleFactory.getVehicle( "truck", {
32 wheelSize: "medium",
33 color: "neon yellow" } );
34
35
36
37
38
39
40

You might also like