用于解析串行字符串的设计模式

时间:2015-03-01 13:13:08

标签: design-patterns string-parsing micr

您对以下案例建议采用何种设计模式:

需要一个类来表示由数字字符组成的某些文档的序列字符串。有4种类型的序列号,字符串的第一个字符指定序列的类型。每种类型的序列都有一些由管道字符分隔的数字字段。串行类型的区别仅在于它们具有的字段数(对于每种类型都是固定的)。每个字段的含义都是无关紧要的,可以有任意值。串行字符串以管道符号结尾,后跟串行所有前面数值的两位校验和。例如,以下字符串表示类型2序列号:

20202 | 5666 | 00020 | 31

这里,第一个数字2指定串行是类型2串行。串行字符串有3个字段,序列的校验和是最后两位数字31,它只是前面所有数字的总和。

在这种情况下,在不使用任何特定模式的情况下解决问题相当容易,但我想知道可以利用哪些着名模式来解决此问题或类似问题(例如,解析钞票的MICR数据) 。

1 个答案:

答案 0 :(得分:0)

正如@ W92所提到的,使用工厂返回解析策略将是一种常见的方法。单独的策略封装了每种类型所需的解析逻辑。 C#示例......

 var serialNumber = "20202|5666|00020|31";
 var factory = new SerialParserFactory();
 var parser = factory.GetParser(serialNumber);
 IParsingResult result = parser.ParseSerial(serialNumber);

解析器都使用单个方法实现公共接口,ParseSerial返回IParsingResult。解析器可以根据需要简单或复杂。

public interface ISerialParser
{
   IParsingResult ParseSerial(string serialNumber);
}

public class SerialParserType2: ISerialParser
    {
        public IParsingResult ParseSerial(string serialNumber)
        {
            string[] parts = serialNumber.Split("|".ToCharArray());

        int[] fields = new int[parts.Length-2];
        for (int partIndex = 0; partIndex < parts.Length-1; partIndex++)
        {
            int value = 0;
            if (!int.TryParse(parts[partIndex], out value))
            {
                value = 0;
            }
            fields[partIndex] = value;
        }
        int checkSum = 0;
        if (!int.TryParse(parts[parts.Length-1], out checkSum))
        {
            checkSum = 0;
        }
        return new Type2Result
        {
            Fields = fields,
            CheckSum = checkSum
        };
    }
}

与结果相同......

public class Type2Result: IParsingResult
{
    public int[] Fields { get; set; }
    public int CheckSum { get; set; }
}

在这种情况下,工厂可以很简单......

public class SerialParserFactory
{
    public ISerialParser GetParser(string serialNumber)
    {
        string typeChar = serialNumber.Substring(0, 1);
        switch (typeChar)
        {
            case "2":
                return new SerialParserType2();
        }
        return new NotFoundParser();
    }
}