简体   繁体   English

用于将一个字符串值映射到另一个字符串

[英]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 我有一个单独的类(适配器)来处理每个外部系统

eg 例如

the state values for my system are 我的系统的状态值是

{ Pending, Booked, Arrived, InProgress, Complete } {Pending,Booked,Arrived,InProgress,Complete}

Now External System A may have the following values 现在, 外部系统A可能具有以下值

{ Unknown, Pending, Booked, Accepted, Arrived, POB, Complete } {Unknown,Pending,Booked,Accepted,Arrived,POB,Complete}

External System B may have the following values 外部系统B可能具有以下值

{ Waiting, Booked, Arrived, InProgress, Complete } {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 对于外部系统A.

Unknown, Pending -> Pending 未知,待定 - >待定

Booked, Accepted -> Booked 已预订,已接受 - >已预订

Arrived, POB -> InProgress 到了,POB - > InProgress

Complete -> Complete 完成 - >完成

For External System B 对于外部系统B.

Waiting -> Pending 等待 - >等待

Booked -> Booked, 预订 - >预订,

Arrived, InProgress -> InProgress 到了,InProgress - > InProgress

Complete -> Complete 完成 - >完成

Now I have abstracted this out to a helper method MapState that each adapter uses to get the state value. 现在我已经将它抽象为一个辅助方法MapState,每个适配器使用它来获取状态值。 This method has string parameters externalsystem, and externalsystemstate and uses switch statements to map the external system state to my system state. 此方法具有字符串参数externalsystem和externalsystemstate,并使用switch语句将外部系统状态映射到我的系统状态。

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: 听起来你需要一个Dictionary来进行有效的查找:

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. 也许使用Hashtable

I think I'd be tempted to use an enum to represent the parsed values, though. 不过,我认为我很想使用enum来表示已解析的值。 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() . 您可以在需要时使用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. 我之前使用的一种方法是创建XML映射文件,这些文件在运行时加载,然后用于将一个值映射到另一个。 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. 在您的代码中,您可以使用XML解析器加载映射,然后查找传入的字符串并查找正确的属性并输出内部值。

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. 在使用State的相同范围内定义这些方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM