What is left for us is to see that with the new hierarchy, we can still do the exact same things:
val rifleman = Soldier(Rifle(), RegularLegs())
val grenadier = Soldier(Grenade(), RegularLegs())
val upgradedGrenadier = Soldier(GrenadePack(), RegularLegs())
val upgradedRifleman = Soldier(MachineGun(), RegularLegs())
val lightRifleman = Soldier(Rifle(), AthleticLegs())
val lightGrenadier = Soldier(Grenade(), AthleticLegs())
Now, our hierarchy looks like this:
Infantry --> Soldier
Weapon --> Rifle
--> MachineGun
--> Grenade
--> GrenadePack
Legs --> RegularLegs
--> AthleticLegs
Much simpler to extend and also to comprehend. Unlike some other design patterns we discussed before, we didn't use any special language feature we didn't know about, just some engineering best practices.