Skip to content

“Strategy” pattern

“Strategy” pattern

One of the primary design patterns is a pattern called “Strategy”. According to the definition this pattern determines a family of algorithms which are placed in separate classes and that makes them fully interchangeable.

Let us analyze this definition on a certain example. We want to create a substitute of a RPG game system. Firstly, we decide to create a number of character professions: Warrior, Mage, Thief, Priest, Berserk, Paladin, Hunter, Druid. These characters can use various kinds of weapons, such as: sword, stick, axe, knives, bow. Additionaly, some of them can cast spells, for example: Fire Ball, Healing, Magic Bullets, Morale and also they can have special abilities like: Sneaking, War Fury, Transformation. Using “Strategy” pattern we can immunize our code to changes, that will probably come when we decide to add new profession or a new behavior. We can proceed with the following task. Namely, we will create classes defining ways of using weapons, which will be implementing common interface. Also, we will do the same thing for spells and special abilities. Whereas, professions will extend the class Character, which in turn will have connection to above mentioned interfaces. After these procedures we will have the opportunity to assign skills to specific characters. In addition, we will be able to assign these dependencies dynamically without modifying the existing code.

Project scheme:

Firstly, let us create the main class – Character:

public abstract class Character {

FightingWithWeapon fightingWithWeapon;
SpellCasting spellCasting;
SpecialAbilities specialAbilities;

public abstract void printCharacterName();

public void makeWeaponAttack() {
fightingWithWeapon.attack();
}

public void chooseAndCastSpell() {
spellCasting.castSpell();
}

public void useSpecialAbility() {
specialAbilities.useAbility();
}

public void setFightingWithWeapon(FightingWithWeapon chosenWeapon) {
fightingWithWeapon = chosenWeapon;
}

public void setSpellCasting(SpellCasting chosenSpell) {
spellCasting = chosenSpell;
}

public void setSpecialAbilities(SpecialAbilities chosenAbility) {
specialAbilities = chosenAbility;
}
}

As we can see, main class has references to the three interfaces grouping ways of using weapons, casting spells and using special abilities. Three last (highlighted) methods in this class will be used for dynamic assigning character’s behaviours. Sample code for the class inheriting from Character class:

public class Mage extends Character {

public Mage() {
spellCasting = new CastingFireBall();
fightingWithWeapon = new StickFighting();
}

public void printCharacterName() {
System.out.println("Profession: Mage.");
}
}

Codes for the above mentioned interfaces and sample classes implementing these interfaces are as follows:

1. Interface and class defining ways of using weapons.

public interface FightingWithWeapon {

void attack();
}
public class SwordFighting implements FightingWithWeapon {

public void attack() {
System.out.println("Sword fighting.");
}
}

2. Interface and class defining spells casting.

public interface SpellCasting {

void castSpell();
}
public class CastingMagicBullets implements SpellCasting {

public void castSpell() {
System.out.println("Casting spell: Magic Bullets.");
}
}

3. Interface and class defining character’s special abilities.

public interface SpecialAbilities {

void useAbility();
}
public class WarFuryAbility implements SpecialAbilities {

public void useAbility() {
System.out.println("War fury!");
}
}

After creating necessary classes we can write the test code in order to check our program. The test code contains references to other professions, weapons, spells and character’s abilities. On this page only sample codes are inserted. However, the general scheme for writing the code is the same as in the above examples.

public class StrategyPatternTest {

public static void main(String[] args) {
Character berserk = new Berserk();
berserk.printCharacterName();
berserk.useSpecialAbility();
berserk.makeWeaponAttack();

Character mage = new Mage();
System.out.println("");
mage.printCharacterName();
mage.chooseAndCastSpell();
mage.setSpellCasting(new CastingMagicBullets());
mage.chooseAndCastSpell();
mage.makeWeaponAttack();

Character thief = new Thief();
System.out.println("");
thief.printCharacterName();
thief.useSpecialAbility();
thief.makeWeaponAttack();

Character warrior = new Warrior();
System.out.println("");
warrior.printCharacterName();
warrior.makeWeaponAttack();
warrior.setFightingWithWeapon(new AxeFighting());
warrior.makeWeaponAttack();

Character paladin = new Paladin();
System.out.println("");
paladin.printCharacterName();
paladin.chooseAndCastSpell();
paladin.makeWeaponAttack();
paladin.setSpellCasting(new CastingHealing());
paladin.chooseAndCastSpell();

Character druid = new Druid();
System.out.println("");
druid.printCharacterName();
druid.makeWeaponAttack();
druid.chooseAndCastSpell();
druid.useSpecialAbility();

Character hunter = new Hunter();
System.out.println("");
hunter.printCharacterName();
hunter.makeWeaponAttack();
hunter.useSpecialAbility();
}
}

Output text from the console:

Profession: Berserk.
War fury!
Axe fighting.

Profession: Mage.
Casting spell: Fire Ball.
Casting spell: Magic Bullets.
Stick fighting.

Profession: Thief.
Sneaking.
Knives fighting.

Profession: Warrior.
Sword fighting.
Axe fighting.

Profession: Paladin.
Casting spell: Morale.
Sword fighting.
Casting spell: Healing.

Profession: Druid.
Stick fighting.
Casting spell: Healing.
Transformation.

Profession: Hunter.
Bow shooting.
Transformation.

Literature sources:
[1] Eric Freeman, Elisabeth Freeman, Kathy Sierra, Bert Bates – “Head First Design Patterns”.

Leave a comment

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