Reputation: 785
I am having a huge switch/case statement which I would like to replace with strategy pattern. Each statement has big peace of code doing the specific logic. Does anyone have a good example of using the pattern in such case, or you have any other good solutions to this?
My solution sofar
class Context
{
private readonly List<CalculationUnit> _calculationsUnits;
public Context()
{
_calculationsUnits = new List<CalculationUnit>()
{
new CalculationUnitA("calc1"),
new CalculationUnitB("calc2"),
new CalculationUnitC("calc2")
};
}
public int Calculate(string name)
{
return (from c in _calculationsUnits where c.Name.Equals(name) select c.Calculate()).FirstOrDefault();
}
}
class CalculationUnit
{
public string Name { get; private set; }
public CalculationUnit(string name)
{
Name = name;
}
public virtual int Calculate()
{
return 0;
}
}
class CalculationUnitA : CalculationUnit
{
public CalculationUnitA(string name) : base(name) { }
public override int Calculate()
{
//calculations logic A
}
}
class CalculationUnitB : CalculationUnit
{
public CalculationUnitB(string name) : base(name) { }
public override int Calculate()
{
//calculations logic A
}
}
class CalculationUnitC : CalculationUnit
{
public CalculationUnitC(string name) : base(name) { }
public override int Calculate()
{
//calculations logic A
}
}
But then I will end up with 50 classes implementing each of the logic...
Thanks
Upvotes: 2
Views: 4687
Reputation: 72860
The strategy pattern helps here by refactoring out the big piece of code in each branch into a separate class (or method). Your switch then becomes simply a case of selecting the appropriate strategy class (or method delegate), which is then executed at the end of the switch statement by a single call. Thus something roughly like this:
switch (...)
{
case ...:
// Horrible logic;
break;
...
}
becomes something like this:
ILogicImplementer implementer;
switch (...)
{
case ...:
implementer = new FirstCaseImplementer();
break;
...
}
implementer.Implement();
You need to refactor the logic into a series of classes implementing a common interface (or extending a common base class), or into a series of methods with compatible signatures so that your strategy can be to select a matching delegate. As Oded implies in his comment, you're not necessarily going to get rid of the select
doing this, but each case will become a lot smaller.
From your brief description, it does sound like the appropriate approach to make your code simpler and more maintainable.
Upvotes: 8