1

これら 2 つのクラスをどのようにリファクタリングして類似点を抽出しますか? 抽象クラス?単純な継承?リファクタリングされたクラスはどのようになりますか?

public class LanguageCode
{
    /// <summary>
    /// Get the lowercase two-character ISO 639-1 language code.
    /// </summary>
    public readonly string Value;

    public LanguageCode(string language)
    {
        this.Value = new CultureInfo(language).TwoLetterISOLanguageName;
    }

    public static LanguageCode TryParse(string language)
    {
        if (language == null)
        {
            return null;
        }

        if (language.Length > 2)
        {
            language = language.Substring(0, 2);
        }

        try
        {
            return new LanguageCode(language);
        }
        catch (ArgumentException)
        {
            return null;
        }
    }
}

public class RegionCode
{
    /// <summary>
    /// Get the uppercase two-character ISO 3166 region/country code.
    /// </summary>
    public readonly string Value;

    public RegionCode(string region)
    {
        this.Value = new RegionInfo(region).TwoLetterISORegionName;
    }

    public static RegionCode TryParse(string region)
    {
        if (region == null)
        {
            return null;
        }

        if (region.Length > 2)
        {
            region = region.Substring(0, 2);
        }

        try
        {
            return new RegionCode(region);
        }
        catch (ArgumentException)
        {
            return null;
        }
    }
}
4

7 に答える 7

2

それは、彼らがそれ以上のことをしないのであれば、おそらくそのままにしておくだろう.

于 2008-09-16T09:16:06.363 に答える
0

これら 2 つは、現状では、静的メソッドのためにうまくリファクタリングできません。

その基本クラスの型を返す基本クラスのある種のファクトリメソッドになるか(後でキャストが必要になります)、または何らかの追加のヘルパークラスが必要になります。

余分なコードの量とその後の適切な型へのキャストを考えると、それだけの価値はありません。

于 2008-09-16T09:21:27.253 に答える
0

より良いジェネリックベースのソリューションがあると確信しています。しかし、それでも試してみました。

EDIT:コメントが言うように、静的メソッドはオーバーライドできないため、1つのオプションはそれを保持し、TwoLetterCodeオブジェクトを使用してキャストすることですが、他の人がすでに指摘しているように、それはかなり役に立ちません.

これはどう?

public class TwoLetterCode {
    public readonly string Value;
    public static TwoLetterCode TryParseSt(string tlc) {
        if (tlc == null)
        {
            return null;
        }

        if (tlc.Length > 2)
        {
            tlc = tlc.Substring(0, 2);
        }

        try
        {
            return new TwoLetterCode(tlc);
        }
        catch (ArgumentException)
        {
            return null;
        }
    }
}
//Likewise for Region
public class LanguageCode : TwoLetterCode {
    public LanguageCode(string language)
    {
        this.Value = new CultureInfo(language).TwoLetterISOLanguageName;
    }
    public static LanguageCode TryParse(string language) {
        return (LanguageCode)TwoLetterCode.TryParseSt(language);
    }
}
于 2008-09-16T09:21:48.610 に答える
0
  1. ジェネリック基本クラスを作成します (例AbstractCode<T>)
  2. のような抽象メソッドを追加します

    protected T GetConstructor(string code);
    
  3. 次のような基本クラスでオーバーライドします

    protected override RegionCode GetConstructor(string code)
    {
        return new RegionCode(code);
    }
    
  4. 最後に、 で同じことを行いますstring GetIsoName(string code)

    protected override GetIsoName(string code)
    {
        return new RegionCode(code).TowLetterISORegionName;
    }
    

それは両方をリファクタリングします。Chris Kimpton は、その努力に見合うだけの価値があるかどうかという重要な問題を提起しています。

于 2008-09-16T09:23:42.193 に答える
0

これはかなり単純な質問で、私にはひどく宿題のようなにおいがします。

明らかにコード内の共通部分を見ることができます。そのようなものをスーパークラスに入れることで、自分で試してみることができると確信しています。

于 2008-09-16T09:19:08.600 に答える
0

Locale言語コードと地域コードの両方を格納し、地域と言語のアクセサーに加えて、「en_gb」などの文字列を許可する1つの解析関数を備えたクラスにそれらを組み合わせることができます...

これが、さまざまなフレームワークでロケールが処理されるのを見てきました。

于 2008-09-16T09:21:05.820 に答える
0

リファクタリングの強い理由がない限り (近い将来、これらのようなクラスを追加する予定であるため)、このような小さくて不自然な例の設計を変更することのペナルティは、このシナリオでのメンテナンスまたはオーバーヘッドの増加を克服します。とにかく、ジェネリック式とラムダ式に基づく可能な設計は次のとおりです。

public class TwoLetterCode<T>
{
    private readonly string value;

    public TwoLetterCode(string value, Func<string, string> predicate)
    {
        this.value = predicate(value);
    }

    public static T TryParse(string value, Func<string, T> predicate)
    {
        if (value == null)
        {
            return default(T);
        }

        if (value.Length > 2)
        {
            value = value.Substring(0, 2);
        }

        try
        {
            return predicate(value);
        }
        catch (ArgumentException)
        {
            return default(T);
        }
    }

    public string Value { get { return this.value; } }
}

public class LanguageCode : TwoLetterCode<LanguageCode>  {
    public LanguageCode(string language)
        : base(language, v => new CultureInfo(v).TwoLetterISOLanguageName)
    {
    }

    public static LanguageCode TryParse(string language)
    {
        return TwoLetterCode<LanguageCode>.TryParse(language, v => new LanguageCode(v));
    }
}

public class RegionCode : TwoLetterCode<RegionCode>
{
    public RegionCode(string language)
        : base(language, v => new CultureInfo(v).TwoLetterISORegionName)
    {
    }

    public static RegionCode TryParse(string language)
    {
        return TwoLetterCode<RegionCode>.TryParse(language, v => new RegionCode(v));
    }
}
于 2008-09-16T09:41:03.277 に答える