JavaScript Design Patterns: Factory Part 2

In the last post, I started talking about the Factory Design Pattern, which creates objects for you, generally all of which follow the same interface. So far we’ve covered the Simple Factory, which creates this functionality in a Singleton object, which is the _simplest _way of creating a Factory, hence its nomenclature (I love that word). This time I’ll show you the true Factory.

What is the True Factory?

The real factory pattern is different from the simple factory because instead of using a separate object to create the cars (in my decorator example), it uses subclasses. The official way to describe the factory pattern goes something like this: “A class that defers instantiation of its member objects to a subclass.”

Car Shop Factory Example

For the example I’ll stick with the car theme, and I’ll even continue using the Car and its decorators that I established in the Decorator Design Pattern post. However I’ll be adding a few car models to mix things up and help show how this really works. Don’t worry, there’s nothing to it; they just subclass from Car, and for the sake of keeping the code terse and because it doesn’t matter, I won’t even show you the implementation of those classes.

We’ll be starting out with a car shop (called CarShop of all things). The car shop is where we’ll be getting our cars from because no smart person actually buys a car from the factory (even though in this example CarShop happens to be a factory). CarShop isn’t actually an object that we can use by itself; it is essentially an abstract class because it implements some functionality, but cannot be instantiated because it leaves some of the functionality to be implemented by the subclasses. Take a look:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* Abstract CarShop "class" */
var CarShop = function(){};
CarShop.prototype = {
sellCar: function (type, features) {
var car = this.manufactureCar(type, features);

getMoney(); // make-believe function

return car;
},
decorateCar: function (car, features) {
/*
Decorate the car with features using the same
technique laid out in CarFactory on my previous
post:
/javascript/javascript-design-patterns-factory/
*/
},
manufactureCar: function (type, features) {
throw new Error("manufactureCar must be implemented by a subclass");
}
};

See the decorateCar method? It’s essentially the same method from the previous Factory Pattern post: CarFactory.makeCar except that it receives the normal Car object as an argument instead of instantiating it. Also notice that manufactureCar is defined, but it just throws an error? It’s up to the subclasses to implement that method. This also happens to be the factory method. Now we’ll make a specific car shop that implements manufactureCar.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* Subclass CarShop and create factory method */
var JoeCarShop = function() {};
JoeCarShop.prototype = new CarShop();
JoeCarShop.prototype.manufactureCar = function (type, features) {
var car;

// Create a different car depending on what type the user specified
switch(type) {
case 'sedan':
car = new JoeSedanCar();
break;
case 'hatchback':
car = new JoeHatchbackCar();
break;
case 'coupe':
default:
car = new JoeCoupeCar();
}

// Decorate the car with the specified features
return this.decorateCar(car, features);
};

This shop only sells cars of the Joe brand, so its factory method has to be different from other shops that sell other types of cars like this next one, which only sells Zim brand vehicles.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* Another CarShop and with factory method */
var ZimCarShop = function() {};
ZimCarShop.prototype = new CarShop();
ZimCarShop.prototype.manufactureCar = function (type, features) {
var car;

// Create a different car depending on what type the user specified
// These are all Zim brand
switch(type) {
case 'sedan':
car = new ZimSedanCar();
break;
case 'hatchback':
car = new ZimHatchbackCar();
break;
case 'coupe':
default:
car = new ZimCoupeCar();
}

// Decorate the car with the specified features
return this.decorateCar(car, features);
};

Using Your Car Shops

Below you’ll see how you would use these newly created car shops. Personally I don’t feel like it’s quite as cool as a simple factory, but if you’re feeling adventurous, you could always make a simple factory to create the shops for you. Then you’ll be stacking factories like a pro!

1
2
3
4
5
6
7
8
9
10
// Use Joe's Shop
var shop = new JoeCarShop();
var car = shop.sellCar("sedan", ["powerlocks"]);

// How about Zim's Shop? Same thing
shop = new ZimCarShop();
car = shop.sellCar("sedan", ["powerlocks"]);

// The shop determines which type of Car we get,
// even if we give the same parameters

Factory Pattern: The Real Conclusion

That wraps it up for the Factory Pattern (for real this time). I hope you learned something otherwise I’m losing sleep for no reason and you’re wasting your time. If, however, you did actually learn something, go ahead and let me know about it via a comment below or maybe let all your friends know via the social sharing buttons that aren’t quite as far below. Happy Coding!

JavaScript Design Patterns series:

Author: Joe Zimmerman

Author: Joe Zimmerman Joe Zimmerman has been doing web development ever since he found an HTML book on his dad's shelf when he was 12. Since then, JavaScript has grown in popularity and he has become passionate about it. He also loves to teach others though his blog and other popular blogs. When he's not writing code, he's spending time with his wife and children and leading them in God's Word.