【问题标题】:Design Pattern for parsing serial strings解析串行字符串的设计模式
【发布时间】:2023-03-15 13:45:01
【问题描述】:

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

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

20202|5666|00020|31

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

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

【问题讨论】:

  • 关于:面料 + 策略。
  • 结构模式和策略模式似乎都是好主意。使用结构模式创建串行对象并使用封装不同串行类型的校验和算法的策略是一个好主意。谢谢@W92。

标签: design-patterns string-parsing micr


【解决方案1】:

正如@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();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多