Challenge: Solution Review
This lesson will explain the solution to the problem from the last coding challenge.
Solution #
Explanation #
Let’s start by going through the original code, so we can understand how to modify it.
You can see that the original code implements inheritance to create a customized character. It has a SuperHero class:
class SuperHero {
constructor(name,power) {
this.name = name
this.power = power
}
}
Each SuperHero instance will have a name and power. Next, there are three child classes all of which extend the functionality of the SuperHero class:
class SuperHeroWithSword extends SuperHero{
//code...
}
class SuperHeroWithSuperSpeed extends SuperHero{
//code...
}
class SuperHeroWithSpeedandSword extends SuperHero{
//code...
}
The extend keyword allows them to inherit the properties of the parent class, SuperHero. They extend the functionality of the SuperHero class by initializing an additional property and a method in their definitions:
class SuperHeroWithSword extends SuperHero{
//code....
this.sword = true
hasSword(){/*code..*/}
}
class SuperHeroWithSuperSpeed extends SuperHero{
//code....
this.superSpeed = true
hasSuperSpeed(){/*code..*/}
}
class SuperHeroWithSpeedandSword extends SuperHero{
//code....
this.speedAndSword = true
hasSpeedAndSword(){/*code..*/}
}
Since each customization (adding a sword, the speed, or both) is a separate class, a superhero can only have one customization at a time. Let’s look at an example:
var superhero1 = new SuperHeroWithSword("Fire Man", "Fire")
Here superhero1 has a sword; however, for it to have both: a sword and the super speed, it will have to be an object of the SuperHeroWithSpeedandSword class.
In a previous lesson, we discussed that when a program has distinct objects with similar underlying code, it is better to use the decorator pattern rather than creating various sub-classes. This allows us to add multiple functionalities to an object. Similarly, the challenge also requires us to modify the code such that each superhero can have various customizations. We can achieve this using the decorator pattern.
Let’s modify each child class according to the decorator pattern:
function SuperHeroWithSword(superhero){
superhero.sword = true
superhero.hasSword= function(){/*code*/}
return superhero;
}
function SuperHeroWithSuperSpeed(superhero) {
superhero.superSpeed = true
superhero.hasSuperSpeed= function(){/*code*/}
return superhero;
}
function SuperHeroWithSpeedandSword(superhero){
superhero.speedAndSword = true
superhero.hasSpeedAndSword = function() {/*code*/}
return superhero;
}
Now, each class is a function that takes the SuperHero object as a parameter, adds new properties/methods to it, and returns it. Hence, it is possible to add various customizations to a superhero now:
var superhero1 = new SuperHero("Fire Man", "Fire")
SuperHeroWithSword(superhero1)
SuperHeroWithSuperSpeed(superhero1)
As you can see, you have the option to add a sword, the super speed, or both to superhero1.
Let’s discuss the facade pattern in the next lesson.