I am working with multiple external systems all of which return a state property.
This state property can be different values between the external systems but must be mapped to a particular state value on my system.
I have a separate class (adapter) to process each external system
eg
the state values for my system are
{ Pending, Booked, Arrived, InProgress, Complete }
Now External System A may have the following values
{ Unknown, Pending, Booked, Accepted, Arrived, POB, Complete }
External System B may have the following values
{ Waiting, Booked, Arrived, InProgress, Complete }
etc, etc
Now I need to map the external system values to my system values.
eg.
For External System A
Unknown, Pending -> Pending
Booked, Accepted -> Booked
Arrived, POB -> InProgress
Complete -> Complete
For External System B
Waiting -> Pending
Booked -> Booked,
Arrived, InProgress -> InProgress
Complete -> Complete
Now I have abstracted this out to a helper method MapState that each adapter uses to get the state value. This method has string parameters externalsystem, and externalsystemstate and uses switch statements to map the external system state to my system state.
I think this is pretty naff and am sure there is a more elegant solution
Any suggestions?
Sounds like you need a Dictionary
for efficient lookup:
var mappingA = new Dictionary<string, string>()
{
{ "Unknown", "Pending" },
{ "Pending", "Pending" },
{ "Booked", "Booked" },
{ "Accepted", "Booked" },
{ "Arrived", "InProgress" },
{ "POB", "InProgress" },
{ "Complete", "Complete" }
};
...then your mapping function can take a reference to the appropriate dictionary:
public string MapState(IDictionary<string, string> mapping, string externalState)
{
return mapping[externalState];
}
Thus:
var state = MapState(mappingA, "Accepted");
...will return "Booked".
Of course you'd want to deal with what should happen if the external state is not in the list of expected values, etc.
I guess you could also save some repetition by excluding the "standard" values from the mapping dictionaries, and only resort to the dictionary if the input is not one of those standard values. Maybe use a Hashtable
for that.
I think I'd be tempted to use an enum
to represent the parsed values, though. That way there's less string manipulation in the downstream code when testing the state. You can easily convert back to a string when you need to, using ToString()
.
An approach I've used before is to create XML mapping files which are loaded in at runtime and then used to map one value to another. For example you could have:
<Input Name="Unknown">
<Output>Pending</Output>
</Input>
<Input Name="Pending">
<Output>Pending</Output>
</Input>
<Input Name="Waiting">
<Output>Pending</Output>
</Input>
This would handle one case of mapping to 'Pending', this also has the advantage that it can be changed outside the program by non-technical users. A disadvantage is that you need to know all the possible incoming types to create a mapping for them.
In your code you could have an XML parser which loaded in the mappings and then it would be a case of looking up the incoming string and finding the correct attribute and outputting the internal value.
You need
enum State { Pending, Booked, Arrived, InProgress, Complete }
out of either:
enum StateA { Unknown, Pending, Booked, Accepted, Arrived, POB, Complete }
enum StateB { Waiting, Booked, Arrived, InProgress, Complete }
then it's as simple as a method to convert (not really a mapping):
State Convert(StateA a)
{
switch(a)
{
case StateA.Unknown:
case StateA.Pending:
return State.Pending;
...
}
}
State Convert(StateB b)
{
...
}
Define those methods in the same scope where State
is used.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.