0

次の場合にどのような設計パターンを提案しますか:

数字で構成される一部のドキュメントのシリアル文字列を表すには、クラスが必要です。シリアルには 4 つのタイプがあり、文字列の最初の文字はシリアルのタイプを指定します。シリアルの各タイプには、パイプ文字で区切られたいくつかの数値フィールドがあります。シリアル タイプの違いは、フィールドの数だけです (タイプごとに固定されています)。各フィールドの意味は無関係であり、任意の値を持つことができます。シリアル文字列はパイプ文字で終わり、その後にシリアルの先行するすべての数値の 2 桁のチェックサムが続きます。たとえば、次の文字列はタイプ 2 のシリアル番号を表します。

20202|5666|00020|31

ここで、最初の桁の 2 は、シリアルがタイプ 2 シリアルであることを示します。シリアル文字列には 3 つのフィールドがあり、シリアルのチェックサムは最後の 2 桁の 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);

すべてのパーサーは、IParsingResult を返す ParseSerial という 1 つのメソッドを持つ共通のインターフェイスを実装しています。パーサーは、必要に応じて単純にすることも複雑にすることもできます。

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 に答える