M
M
mletov2018-01-29 10:01:37
OOP
mletov, 2018-01-29 10:01:37

How to replace switch case with strategy pattern?

I looked through the vacancies here, one of them contained a rather interesting wording of something like this:
"We expect the programmer to understand and actively use design patterns, but without fanaticism. For example, every switch case will not be rewritten into a strategy."
As I understand it, I meant the pattern of the same name. So it became interesting to me how they can replace the switch case. After all, branching is still needed to choose a strategy. for example

switch (x)
{
     case 1:
        obj.strategy = new Strategy1();
    break;

     case 2:
        obj.strategy = new Strategy2();
    break;
}

I would appreciate code examples.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexey Pavlov, 2018-01-29
@mletov

switch

public enum DamageType { Melee, Range, Magic }
public class Monster
{
    public double Health { get; private set; }
    public double MeleeDamage { get; private set; }
    public double RangeDamage { get; private set; }
    public double MagicDamage { get; private set; }
    public DamageType FavoriteDamageType { get; private set; }

    public Monster(double health, double meleeDamage, double rangeDamage, double magicDamage, DamageType favoriteDamageType)
    {
        Health = health;
        MeleeDamage = meleeDamage;
        RangeDamage = rangeDamage;
        MagicDamage = magicDamage;
        FavoriteDamageType = favoriteDamageType;
    }

    public void AttackTo(Monster monster, DamageType damageType)
    {
        switch (damageType) // используется switch
        {
            case MonsterType.Melee: monster.Health -= MeleeDamage; break;
            case MonsterType.Range: monster.Health -= RangeDamage; break;
            case MonsterType.Magic: monster.Health -= MagicDamage; break;
        }
    }

    public void AttackTo(Monster monster)
    {
        AttackTo(monster, FavoriteDamageType);
    }
}

Same thing but with a strategy
public class Monster
{
    public double Health { get; set; }
    public double MeleeDamage { get; private set; }
    public double RangeDamage { get; private set; }
    public double MagicDamage { get; private set; }
    public IDamageStrategy FavoriteDamageStrategy { get; private set; }

    public Monster(double health, double meleeDamage, double rangeDamage, double magicDamage, IDamageStrategy favoriteDamageStrategy)
    {
        Health = health;
        MeleeDamage = meleeDamage;
        RangeDamage = rangeDamage;
        MagicDamage = magicDamage;
        FavoriteDamageStrategy = favoriteDamageStrategy;
    }

    public void AttackTo(Monster monster, IDamageStrategy damageStrategy)
    {
        damageStrategy.Attack(this, monster); // не используется switch
    }

    public void AttackTo(Monster monster)
    {
        AttackTo(monster, FavoriteDamageStrategy);
    }
}


public interface IDamageStrategy
{
    void Attack(Monster attacker, Monster defender);
}
public class MeleeDamageStrategy : IDamageStrategy 
{
    public void Attack(Monster attacker, Monster defender)
    {
        defender.Health -= attacker.MeleeDamage;
    }
}
public class RangeDamageStrategy : IDamageStrategy 
{
    public void Attack(Monster attacker, Monster defender)
    {
        defender.Health -= attacker.RangeDamage;
    }
}
public class MagicDamageStrategy : IDamageStrategy 
{
    public void Attack(Monster attacker, Monster defender)
    {
        defender.Health -= attacker.MagicDamage;
    }
}

The difference between the Monster class is only in the code of the first AttackTo method. Well, the FavoriteDamageType or FavoriteDamageStrategy properties.
The strategy can be useful if the attack code, depending on the type, is very different, using external data (not from the monster class), for example, day or night, clear / rain, etc. Using the strategy transfers part of the code from the monster class (and so complex class) into several simple classes.

M
Maxim Fedorov, 2018-01-29
@qonand

Switch is not used to select a strategy. The desired strategy object is simply passed to the class. An example can be seen here

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question