Based on a passed parameter containing a type I'm looking for a better way to initialize the class based on that type. Currently I'm "solving" it with a switch statement which is feels quite redundant.
Bad example showing what the functionality is:
protected Quest GenerateQuest(QuestConfiguration questConfiguration)
{
List<QuestObjective> objectives = new();
foreach ( QuestObjectiveConfiguration questConfigurationObjective in questConfiguration.ObjectiveConfigurations)
{
switch (questConfigurationObjective.ObjectiveType)
{
case ObjectiveType.Fetch:
objectives.Add(new ObjectiveFetch(questConfigurationObjective.InternalId));
break;
case ObjectiveType.Gather:
objectives.Add(new ObjectiveGather(questConfigurationObjective.InternalId));
break;
case ObjectiveType.Craft:
objectives.Add(new ObjectiveCraft(questConfigurationObjective.InternalId));
break;
case ObjectiveType.Deliver:
objectives.Add(new ObjectiveDeliver(questConfigurationObjective.InternalId));
break;
case ObjectiveType.Combat:
objectives.Add(new ObjectiveCombatEncounter(questConfigurationObjective.InternalId));
break;
default:
throw new ArgumentOutOfRangeException();
}
}
return new Quest(objectives);
}
Looked/googled for suiting patterns but I'm having a hard time getting specific results because the related terms are generic and the issue is an edgecase.
If the QuestObjective
can be created with just QuestObjectiveConfiguration
, then I'd consider having the switch statement in a method or extension method of it.
This of course does not get rid of the switch statement but atleast keeps it in one place.
static class QuestObjectiveConfigurationExtensions
{
public static QuestObjective ToQuestObjective(
this QuestObjectiveConfiguration config) => config.ObjectiveType switch
{
ObjectiveType.Fetch => new ObjectiveFetch(config.InternalId),
//rest of your types
_ => //maybe throw an Exception here
};
}
This shortens your objective creation to
var objectives = questConfiguration.ObjectiveConfigurations.Select(x => x.ToQuestObjective)
You can do the same for QuestConfiguration
and Quest
of course and implement a ToQuest
method.
One option to get rid of the switch statement completely would be to have different types of QuestObjectiveConfiguration
that implement different methods of ToQuestObjective
.