0

对于以下情况,您建议使用哪种设计模式:

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

20202|5666|00020|31

此处,第一个数字 2 指定该序列号为 2 型序列号。序列号字符串有 3 个字段,序列号的校验和是最后两位数字 31,它只是前面所有数字的总和。

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

4

1 回答 1

0

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

 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();
    }
}
于 2015-03-01T16:34:56.993 回答