您对以下案例建议采用何种设计模式:
需要一个类来表示由数字字符组成的某些文档的序列字符串。有4种类型的序列号,字符串的第一个字符指定序列的类型。每种类型的序列都有一些由管道字符分隔的数字字段。串行类型的区别仅在于它们具有的字段数(对于每种类型都是固定的)。每个字段的含义都是无关紧要的,可以有任意值。串行字符串以管道符号结尾,后跟串行所有前面数值的两位校验和。例如,以下字符串表示类型2序列号:
20202 | 5666 | 00020 | 31
这里,第一个数字2指定串行是类型2串行。串行字符串有3个字段,序列的校验和是最后两位数字31,它只是前面所有数字的总和。
在这种情况下,在不使用任何特定模式的情况下解决问题相当容易,但我想知道可以利用哪些着名模式来解决此问题或类似问题(例如,解析钞票的MICR数据) 。
答案 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();
}
}