I have a state machine that needs to call a different method on each object from a List of objects depending on the state I'm in. Basically I'm trying to refactor the code that has a loop in each case statement of my state machine so that it looks like the code below. However I cannot seem to figure out how to pass the relevant method to my refactored function (not to mention I then don't know how to call it on each item)
Any help would be appreciated.
Here's the example code:
public class MyOtherType
{
public bool Method1()
{ return false; }
public bool Method2()
{ return false; }
public bool Method3()
{ return false; }
public bool Method4()
{ return false; }
}
public class MyType
{
public enum MyState
{
DoSomething1,
DoSomething2,
DoSomething3,
DoSomething4
}
private MyState State = MyState.DoSomething1;
List<MyOtherType> MyListOfObjects = new List<MyOtherType>() { new MyOtherType(), new MyOtherType() };
private void StateMachine()
{
switch (State)
{
case MyState.DoSomething1:
//How do I pass this in? Do I need to set it up differnetly?
Process(() => MyOtherType.Method1());
break;
case MyState.DoSomething2:
Process(() => MyOtherType.Method2);
break;
case MyState.DoSometh开发者_StackOverflowing3:
Process(() => MyOtherType.Method3);
break;
case MyState.DoSomething4:
Process(() => MyOtherType.Method4);
break;
}
}
private void Process(Func<bool> method)
{
foreach (MyOtherType item in MyListOfObjects)
{
//How do I call the method on each item?
if (item.method())
{
//Do something
}
}
}
}
I would suggest to get rid of such switch
blocks and decouple each specific method from a state by introducing flexible map of strategy per state so it could be easily changed or even injected:
IDictionary<MyState, Func<bool>> strategyMap;
1) Fill it in
// if idea is to access methods without instance of MyOtherType -
// make all methods and class itself static so you can access it
// like MyOtherType.Method1
strategyMap = new Dictionary<MyState, Func<bool>>();
strategyMap.Add(MyState.DoSomething1, myOtherTypeInstance.Method1);
2) Call appropriate strategy depends on state instead of switch(State)
if (starategyMap.ContainsKey(State))
{
// pass in an associated strategy
Process(starategyMap[State]);
}
Feel free to ask in case of any questions
One possible solution is to make the methods static and take the class reference they shall operate on as a parameter:
public class MyOtherType
{
public static bool Method1(MyOtherType instance)
{
return instance == null;
}
}
精彩评论