Challenge: Solution Review

This lesson will explain the solution to the problem from the last coding challenge.

We'll cover the following

Solution #

function ToyFactory() {
this.toy = ToyDuck;
this.createToy = function(toyChosen) {
if (toyChosen.toyType == "duck") {
this.toy = ToyDuck;
} else if (toyChosen.toyType == "car") {
this.toy = ToyCar;
}
return new this.toy(toyChosen);
}
}
function ToyDuck(toyObj) {
this.color = toyObj.color;
this.price = toyObj.price;
}
function ToyCar(toyObj) {
this.color = toyObj.color;
this.price = toyObj.price;
this.name = toyObj.name;
}
var toyFactory = new ToyFactory();
var car = toyFactory.createToy({
toyType: "car",
color: "blue",
price: 12,
name: "honda"
})
var car = toyFactory.createToy({
toyType: "car",
color: "blue",
price: 12,
name: "honda"
})
console.log(car)
console.log(car instanceof ToyCar)
var duck = toyFactory.createToy({
toyType: "duck",
color: "yellow",
price: 5,
})
console.log(duck)
console.log(duck instanceof ToyDuck)

Explanation

The task was to create a function createToy, which instantiated either a ToyDuck or a ToyCar object.

We start by defining the constructor functions. Let’s take a look at them.

  • ToyDuck

    function ToyDuck(toyObj){
      this.color = toyObj.color;
      this.price = toyObj.price;
    }
    

    It accepts a parameter toyObj, that is, the “toy object” and sets its color equal to toyObj.color and price equal to toyObj.price.

  • ToyCar

    function ToyCar(toyObj){
      this.color = toyObj.color;
      this.price = toyObj.price;
      this.name =  toyObj.name;
    } 
    

    It accepts a parameter toyObj, that is, the “toy object” and sets its color equal to toyObj.color, price equal to toyObj.price and name equal to toyObj.name.

Now that we have defined our constructor functions, we implement the factory pattern by implementing the createToy method.

We define this method inside the ToyFactory constructor function. Let’s look at it in detail:

function ToyFactory() {
    this.toy = ToyDuck;
    this.createToy = function(toyChosen) {
        if (toyChosen.toyType == "duck") {
            this.toy = ToyDuck;
        } else if (toyChosen.toyType == "car") {
            this.toy = ToyCar;
        }
        return new this.toy(toyChosen);
    }
}

First, we have the toy value set to ToyDuck constructor function (for ease, let’s refer to these as “class”). What we want is to create either a duck or a car toy, depending upon the requirement.

The createToy method accepts a parameter toyChosen. Next, it checks whether the type of the toyChosen is duck or car. You can see this on lines 4 & 6.

if (toyChosen.toyType == "duck") //line 4
else if (toyChosen.toyType == "car") //line 6

The toyType property stores the type of the toy, i.e., duck or car. Depending on its value, it sets toy value equal to either ToyDuck class or ToyCar class. You can see this on lines 5 & 7.

this.toy = ToyDuck //line 5
this.toy = ToyCar //line 7

In the end, the function instantiates an object of the required class (depending on the class stored in toy) and returns the object. You can see this on line 9.

return new this.toy(toyChosen); //line 9

Let’s run our implementation for the following example:

var toyFactory = new ToyFactory();
var car = toyFactory.createToy({
    toyType: "car",
    color: "blue",
    price: 12,
    name: "honda"
})
  • First, we instantiate an object of the ToyFactory class called toyFactory.

  • Next, we invoke the createToy function and pass an object as a parameter to it.

  • In the createToy function, the line toyChosen.toyType == "car" will evaluate to true; hence, toy will be set to the ToyCar class.

  • In the end, an object of the ToyCar class is instantiated and returned.

Hence, the toy objects aren’t instantiated with new directly; instead, you directly called createToy which handles the object creation.


Let’s discuss the constructor pattern in the next lesson.