Я плохо знаком с шаблонами разработки и таким образом имею ограниченные знания того, что все доступно. Надо надеяться, я могу предоставить некоторую подробную информацию вокруг проблемы, которую я пытаюсь решить, и пользовательское сообщество может дать некоторые указания на то, какой шаблон разработки использовать и как оно должно быть реализовано.
Например:
public enum ActionType
{
Action1,
Action2,
Action3
}
Возможная реализация шаблона "фабрика":
public static class ActionClass
{
public static int DoAction(ActionType type, int val1, int val2)
{
switch (type)
{
case Type1:
return new ActionClass1(val1, val2).DoAction();
break;
default:
throw new NotImplementedException();
}
}
public static int DoAction(ActionType type, string val1)
{
switch (type)
{
case Type2:
return new ActionClass2(val1).DoAction();
break;
case Type3:
return new ActionClass3(val1).DoAction();
default:
throw new NotImplementedException();
}
}
}
В зависимости от того, что представляют собой ваши действия, вы можете захотеть взглянуть на шаблон стратегии . В противном случае шаблон фабричного метода уже выглядит хорошо подходящим, хотя я бы, вероятно, изменил метод, чтобы не выполнять действие немедленно, а возвращал объект, инкапсулирующий действие, и использовал шаблон TryXXX вместо исключения, когда действие не поддерживает типы параметров:
public static bool TryGetIntIntAction(
ActionType type, out Func<int, int, int> func)
{
switch (type)
{
case ActionType.Action1:
func = (val1, val2) => new ActionClass1(val1, val2).DoAction();
return true;
default:
func = null;
return false;
}
}
public static bool TryGetStringAction(
ActionType type, out Func<string, int> func)
{
switch (type)
{
case ActionType.Action2:
func = val1 => new ActionClass2(val1).DoAction();
return true;
case ActionType.Action3:
func = val1 => new ActionClass3(val1).DoAction();
return true;
default:
func = null;
return false;
}
}
Обычный способ рефакторинга переключателей на типы - полиморфизм, путем создания класса для каждого ActionType
. Поскольку каждая перегрузка DoAction
принимает различные параметры, вы можете заключить их в "объект параметра" и связать каждый тип действия с его типом параметра с помощью generics:
public abstract ActionClass<T>
{
public abstract int DoAction(T parameter);
}
public class ActionClass2 : ActionClass<string>
{
public override int DoAction(string parameter) { ... }
}