Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

elegant solution for mapping one string value to another

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

e.g

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?

like image 539
macca18 Avatar asked Sep 22 '15 10:09

macca18


1 Answers

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().

like image 123
Gary McGill Avatar answered Nov 14 '22 08:11

Gary McGill