Dot-Net
隨著擴展方法的出現,抽像類的吸引力是否降低了?
.NET 中擴展方法的一個有趣方面是您可以將它們應用於介面。對我來說,我可以在介面附近定義功能而不定義使程序集混亂的抽像類似乎很好。
我知道抽像類並沒有過時或任何東西,但是您對在程式碼中使用這種副作用有何感想?
例子:
public static class IUserExtensions { public static bool IsCurrentUser(this IUser user) { return (HttpContext.Current.User != null && HttpContext.Current.User.Identity.Name == user.ID.ToString()); } } public interface IUser { int ID { get; set; } }
擴展方法可以讓您專注於抽像類實際上應該做什麼。在抽像類中實現“實用程序”程式碼是一種誘惑,因為即使它可能不是邏輯繼承樹的一部分,實現者也會使用它。擴展方法讓您可以將這些實用方法附加到介面,而不會弄亂抽象基類。
編輯
具體來說,我會應用這些準則。
遺產
- 如果行為是基類的邏輯行為的一部分,請使用繼承
- 如果行為是橫切的(適用於對象層次結構之外的事物),則不要使用繼承。這些將需要複製。
實用程序類
- 如果行為在邏輯上不屬於它所作用的類,請使用實用程序類(靜態類)
- 如果實用程序類修改了它所作用的對象的內部狀態,則不要使用它們。狀態修改應該只保留給對象實現層次結構。
擴展方法
- 當擴展方法產生較少摩擦時,請使用與實用程序類相同的決定。如果採用擴展方法感覺不太自然,請不要這樣做。
- 請使用擴展方法將實用程序添加到您無法控制的類(如字元串)。
- 當行為被它所擴展的類使用時,不要使用擴展方法。雖然可以做到,但感覺做作
- 不要僅僅因為可以就使用擴展方法。事實上,除非你必須這樣做,否則不要偏離良好的老式 OOP 。然而,當你不得不做的時候,擴展方法是一個相對無用且無害的決定。
編輯 2
想到另一個 DO 擴展方法
請使用擴展方法為某些實現提供自然語言(內部 DSL)。這是一個愚蠢的例子。
int age = getAge(); if (age.IsDraftAge() && !age.IsLegalDrinkingAge()) { Console.WriteLine(@"You cannot drink until your birthdate on {0}. Join the army instead.", age.GetYearWhenGettingDrunkIsOk()); }