Pergunta

Como você refatorar essas duas classes abstratas, as semelhanças?Uma classe abstrata?Herança simples?O que seria o refatorado classe(s) de aparência?

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;
        }
    }
}
Foi útil?

Solução

A menos que você tenha um motivo forte para refatoração (porque você está indo para adicionar mais aulas como essas no futuro próximo), a pena de alterar o design para um pequeno e artificial exemplo seria superar o ganho em manutenção ou suspensos neste cenário.De qualquer forma, aqui está um possível projeto com base no genérico e expressões lambda.

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));
    }
}

Outras dicas

Depende, se eles não vão fazer muito mais, então eu provavelmente iria deixar como está - IMHO de factoring, as coisas tendem a ser mais complexos, neste caso.

Esta é uma pergunta simples e, para mim, cheira awefully como um dever de casa.

Obviamente, você pode ver o comum bits no código e eu tenho certeza que você pode fazer uma tentativa em você mesmo colocando essas coisas em uma super-classe.

Você poderia talvez combiná-los em um Locale classe, que armazena código de Linguagem e código de Região, tem acessores para a Região e o Idioma mais uma função de análise que também permite que, para seqüências como "pt_br"...

É assim que eu tenho visto localidades de ser tratada em vários quadros.

Estes dois, como ficar, não vamos refatorar bem, porque de métodos estáticos.

Você teria que quer acabar com algum tipo de fábrica método em uma classe base que retorna um tipo da classe base (que seria posteriormente necessidade de fundição) ou você precisa de algum tipo de adicional de auxiliar de classe.

Dada a quantidade extra de código e as casting para o tipo apropriado, não vale a pena.

  1. Criar uma classe base genérica (por exemplo, AbstractCode<T>)
  2. adicionar métodos abstratos como

    protected T GetConstructor(string code);
    
  3. substituição de classes base como

    protected override RegionCode GetConstructor(string code)
    {
        return new RegionCode(code);
    }
    
  4. Finalmente, faça o mesmo com string GetIsoName(string code), por exemplo,

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

Que vai reestruturar a ambos.Chris Kimpton levanta a importante questão de saber se o esforço vale a pena.

Eu tenho certeza que é melhor que os genéricos solução.Mas ainda deu-lhe um tiro.

EDITAR:Como o comentário diz, métodos estáticos não pode ser substituído, portanto, uma opção seria a de reter e utilizar TwoLetterCode objetos e lançá-los -, mas, como algumas outras pessoas já se assinalou, o que é bastante inútil.

Quanto a isso?

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);
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top