Strategy Design Pattern Example

Strategy Design Pattern is used to manage multiple subclasses (each implements various behaviors and shares some common behaviors) via composition instead of inheritance. This design pattern encapsulates each algorithm to be used interchangeably during runtime depending on client usage.

Basic Coding

This is what I used to code in my previous works. It’s simple and gets the thing done. When there are more weapons added, this class will be modified again. This poses risks where changing a class after testing might break it. Also, if there is complex formula involved in calculating the output for each weapon, this Weapon Class will be very difficult to read with hundreds or thousands lines of codes.

public class Weapon extends Object
{
   public var attack:int;
   public var soundEffect:String;

   public function getDamage(weaponType:String):int
   {
      if (weaponType == 'Sword' || weaponType == 'Spear')
      {
         return attack * 10;
      }
      if (weaponType == 'Bow' || weaponType == 'Crossbow')
      {
         return attack * 8;
      }
      return 0;
   }
   public function getSound(weaponType:String):int
   {
      if (weaponType == 'Sword' || weaponType == 'Bow')
      {
         return 'Boing';
      }
      if (weaponType == 'Spear' || weaponType == 'Crossbow')
      {
         return 'Boom';
      }
      return '';
   }
}

Advance Coding

Here I breakdown the main code into Interfaces and Multiple Classes. It seems that it requires more effort and more lines of codes compared to the basic coding. However, in the long term, it is easier to maintain the code as each class only holds a small portion of code (easier to read and find). Advance coding applies polymorphism (object with same method but does different things) and adheres to the principal of “Open for Extension, Close for Modification”.

public interface DamageFormula
{
   function getDamage():int;
}

public class MeleeDamageFormula implements DamageFormula
{
   public function getDamage(attack:int):int { return attack * 10; }
}

public class RangeDamageFormula implements DamageFormula
{
   public function getDamage(attack:int):int { return attack * 5; }
}

public interface SoundEffect
{
   function getSound():String;
}

public class BoingSoundEffect implements SoundEffect
{
   public function getSound():String { return 'Boing'; }
}

public class BoomSoundEffect implements SoundEffect
{
   public function getSound():String { return 'Boom'; }
}

public interface Weapon
{
   function getDamage():int;
   function getSound():String;
}

public class Sword implements Weapon
{
   public var attack:int;
   public var damageFormula:DamageFormula = new MeleeDamageFormula();
   public var soundEffect:SoundEffect = new BoingSoundEffect();
   public function getDamage():int { damageFormula.getDamage(attack); }
   public function getSound():String { soundEffect.getSound(); }
}

public class Spear implements Weapon
{
   public var attack:int;
   public var damageFormula:DamageFormula = new MeleeDamageFormula();
   public var soundEffect:SoundEffect = new BoomSoundEffect();
   public function getDamage():int { damageFormula.getDamage(attack); }
   public function getSound():String { soundEffect.getSound(); }
}

public class Bow implements Weapon
{
   public var attack:int;
   public var damageFormula:DamageFormula = new RangeDamageFormula();
   public var soundEffect:SoundEffect = new BoingSoundEffect();
   public function getDamage():int { damageFormula.getDamage(attack); }
   public function getSound():String { soundEffect.getSound(); }
}

public class Crossbow implements Weapon
{
   public var attack:int;
   public var damageFormula:DamageFormula = new RangeDamageFormula();
   public var soundEffect:SoundEffect = new BoomSoundEffect();
   public function getDamage():int { damageFormula.getDamage(attack); }
   public function getSound():String { soundEffect.getSound(); }
}

Summary

If I had to add more weapons and sound effects, basic coding becomes really messy and difficult to read with all of the if-statements conditions whereas for Advance Coding, it requires some time to properly manage these classes into folders.

The codes in Advance Coding section can be further simplified by implementing Factory Pattern which will be discussed in my subsequent post!

Leave a Reply

Your email address will not be published. Required fields are marked *