Frage

Wie würden Sie diese beiden Klassen zu abstrahieren die Ähnlichkeiten Refactoring? Eine abstrakte Klasse? Einfache Vererbung? Was wäre die Überarbeitete Klasse (n) aus?

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;
        }
    }
}
War es hilfreich?

Lösung

Es sei denn, Sie haben einen starken Grund für Refactoring (weil Sie wollen mehr Klassen, wie sie in naher Zukunft hinzufügen) die Strafe den sich mit der Gestaltung für ein so kleines und erfundenes Beispiel würde die Verstärkung in der Instandhaltung oder über Kopf in diesem Szenario überwinden . Auf jeden Fall ist hier ein möglicher Entwurf basiert auf der allgemeinen und Lambda-Ausdrücke.

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

Andere Tipps

Es hängt davon ab, ob sie nicht viel mehr tun werden, dann würde ich sie wahrscheinlich verlassen, wie ist -. IMHO Sachen Ausklammern ist wahrscheinlich komplexe, in diesem Fall sein

Dies ist eine ziemlich einfache Frage und ich rieche awefully wie eine Hausaufgabe.

Sie können natürlich die gemeinsamen Bits in dem Code sehen, und ich bin mir ziemlich sicher, dass man es selbst einen Versuch machen, kann durch solche Dinge in eine Super-Klasse setzen.

Sie könnten sie vielleicht in eine Locale Klasse kombinieren, die sowohl Sprachcode und Regionalcode speichert, hat Accessoren für Region und Sprache plus eine Parse-Funktion, die auch für Zeichenketten wie „en_gb“ erlaubt ...

Das ist, wie ich habe locales in verschiedenen Frameworks behandelt gesehen werden.

Diese beiden, wie sie stehen, werden nicht gut Refactoring wegen der statischen Methoden.

Sie würden entweder mit irgendeiner Art von Factory-Methode auf einer Basisklasse am Ende, die eine eine Art dieser Basisklasse zurückgibt (die anschließend Gießen benötigen würde) oder würden Sie eine Art von zusätzlichen Hilfsklasse benötigen.

die Menge an zusätzlichem Code und anschließenden Gießen in dem entsprechenden Typ gegeben, dann ist es nicht wert.

  1. Erstellen Sie eine generische Basisklasse (zB AbstractCode<T>)
  2. hinzufügen abstrakte Methoden wie

    protected T GetConstructor(string code);
    
  3. Überschreibung in Basisklassen wie

    protected override RegionCode GetConstructor(string code)
    {
        return new RegionCode(code);
    }
    
  4. Schließlich das gleiche mit string GetIsoName(string code), zB

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

Das wird die beide Refactoring. Chris Kimpton hat die wichtige Frage aufwerfen, ob der Aufwand lohnt sich.

Ich bin sicher, dass es eine bessere Generika basierte Lösung. Aber gab es noch einen Schuss.

EDIT: Wie der Kommentar sagt, können statische Methoden nicht so eine Option außer Kraft gesetzt werden würde, es zu behalten und TwoLetterCode Objekte verwenden, um und wirft sie, aber, wie eine andere Person hat bereits darauf hingewiesen, dass ziemlich nutzlos ist.

Wie wäre das?

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);
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top