2013-01-17 127 views
1

我正在對提供數據的API進行更改(這是對我的original question的更新)。某些搜索需要關於作者的數據並採用IAuthor對象。該API具有一個IAuthor接口和一個實現IAuthor的單個具體類,稱爲Author擴展(不更改)搜索類的新行爲?

我需要改變Search.GetBooksByAuthor方法的行爲,以便在作者被標記爲小說家時賦予不同的語義。我聽說open/closed principle,看起來改變IAuthor和/或Author和/或Search類會違反這一點(雖然Book類絕對保持不變)。那麼如何做出這個簡單的改變?

例如,我本來想這樣的,但我的想法是靠不住的可能,因爲它涉及到改變的Search類:

//Before 
class Search 
{ 
    public Books[] GetBooks(IAuthor author){ 
     // Call data access GetBooks... 
    } 
} 


//After 
class Search 
{ 
    public Books[] GetBooks(IAuthor author){ 
     // To maintain pre-existing behaviour 
     // call data access GetBooks method with SQL param @AsNovelist = false... 
     // (or don't pass anything because the SQL param defaults to false) 
    } 

    public Books[] GetBooksAsNovelist(IAuthor author){ 
     // To get new behaviour 
     // call data access GetBooks method with SQL param @AsNovelist = true 
     // so that their non-fiction books are omitted from results 
    } 
} 
+1

你能簡單地定義一個布爾成員'IsNovelist'在界面中? – LukeHennerley

回答

1

看起來很明顯某些東西需要改變以便知道你的作者是否是Novelist,你可以通過兩種方法做到這一點。你不需要理論上改變任何東西,但是你需要一個新的課程。

public class Novelist : Author, IAuthor { } 

然後,您可以將小說家傳入您的方法,然後確定您的作者類型。

class Search 
{ 
    public Books[] GetBooks(IAuthor author){ 
     if(author is Novelist) 
     //Do some stuff or set a flag/bool value 
    } 
} 

或者如前所述,實現布爾成員到您的作者接口並檢查。上面的內容會阻止你改變你的類結構。

這意味着你的小說家實際上仍然是作者,它只是它自己的類型。你的方法簽名保持不變,你的類結構保持不變,你只需要一個「不同類型的作者」,這在理論上應該是好的。請按以下方式進行測試。

GetBooks(new Novelist()); 
1

如何使用謂詞進行過濾?

class Search 
{ 
    public Books[] GetBooks(IAuthor author, Func<IAuthor, bool> filter){ 
     // ... 
    } 
} 

search.GetBooks(author, a => a.IsNovelist) 
+0

我喜歡它,但它涉及到更改'Search'類,所以不會違反開放式封閉原則? – petemoloy

+0

@petemoloy:拜託,別做OOP原則狂熱。 :)他們不是教條,必須與大腦同時應用。在這個具體的用例中違反O/C原則是否有不良副作用? – Dennis

+0

採取了點。我相信你知道它是如何的:對你而言(OOP)有些新東西,所以你儘早閱讀一些東西,然後花更多時間在所有的建議中瀏覽你自己的路徑。謝謝。 – petemoloy

0

保持搜索類方法爲虛擬的,因此任何人都可以重寫它們來創建新的行爲?

1

爲了擴展類C#.NET使用.NET 3.5,其主要目的正是爲了擴展一個類,而無需修改現有的代碼介紹extension methods

public static class SearchExtensions 
{ 
    public static Books[] GetBooksAsNovelist(this Search search, IAuthor author) 
    { 
    // Perform novelist search 
    } 
} 

然後,你可以調用你的搜索類通常用:

Search.GetBooksAsNovelist(author); 
+0

我檢查了:我必須瞄準.NET 2.0 :( – petemoloy

1

您可以使用C#語言的擴展功能。

請參閱http://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx

擴展使通過保持完好類功能添加到類。

在你的情況,你可以寫爲:

public static class SearchExtensions 
    { 
     public static Books[] GetBooks(this Search search, IAuthor author) 
     { 
      //new logic 
     } 
    } 

您可以訪問由搜索對象這種新的方法和搜索類也保持不變。

請讓我知道,如果你覺得這有幫助。

1

你可以讓你的類偏能夠添加functionalyti沒有擴展,或繼承,或控制反轉:

// file: Search.cs 

partial class Search 
{ 
    public Books[] GetBooks(IAuthor author) { ... } 
} 

// file: Search.Advanced.cs 

partial class Search 
{ 
    public Books[] GetBooksAsNovelist(IAuthor author) { ... } 
} 

結果:

http://i.snag.gy/VowNv.jpg

+0

該類不是現在部分,所以不會改變它成爲部分違反開放封閉原則? – petemoloy

+0

@petemoloy當然它不會。你可以使用'new'關鍵字隱藏班級成員 – AgentFire

+0

這真的很明顯,我在那裏做了一個錯誤陳述?我對OOP比較陌生,所以我必須聽取你的意見;) – petemoloy