2008-09-16 87 views
1

你會如何重構這兩個類來抽象出相似之處?抽象類?簡單的繼承?重構類(es)看起來像什麼?重構兩個基本類

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

回答

0

除非你有很強的重構原因(因爲你打算在不久的將來增加更多的類),爲這樣一個小而人爲的例子改變設計的懲罰將克服維護或開銷的增益場景。無論如何,這裏是基於泛型和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)); 
    } 
} 
2

這取決於,如果他們不打算做更多的事情,那麼我可能會離開他們的是 - 恕我直言,分解出的東西很可能是更加複雜,在這種情況下。

0

這是一個相當簡單的問題,對我來說,就像做家庭作業一樣。

你很明顯可以看到代碼中的常見部分,我敢肯定你可以自己嘗試一下,把這些東西放進一個超類。

0

也許你可以將它們組合成一個Locale類,它同時存儲語言代碼和地區代碼,對區域和語言加一個解析功能,還可以像「EN_GB」串存取...

這我如何在各種框架中看到區域設置。

0

這兩個,因爲他們的立場,不會因爲靜態方法而重構。

你最終會在基類中得到某種工廠方法,該方法返回一個基類的類型(隨後需要轉換)或者你需要某種類型的輔助類。

考慮到額外代碼的數量並隨後轉換爲適當的類型,這不值得。

0

我確定有更好的基於泛型的解決方案。但仍然給它一個鏡頭。

編輯:正如評論所說,靜態方法不能被覆蓋,所以一個選項將保留它並使用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); 
    } 
} 
+0

不幸的是,這不會很好,因爲你的TryParse方法不是靜態的。 TryParse是一個有效的工廠方法,它返回一個新的LanguageCode或RegionCode對象。在你的例子中,你需要先創建一個對象。你不能重寫基礎TryParse,因爲它是靜態的。 – 2008-09-16 09:28:04

0
  1. 創建一個通用基類(如AbstractCode<T>
  2. 添加的抽象方法,如

    protected T GetConstructor(string code); 
    
  3. 覆蓋在基礎類

    protected override RegionCode GetConstructor(string code) 
    { 
        return new RegionCode(code); 
    } 
    
  4. 最後,做與0相同,如

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

這將重構兩者。 Chris Kimpton確實提出了一個重要的問題,那就是努力是否值得。