为新行为扩展(而不是更改)搜索类?

我正在更改提供数据的API(这是我原始问题的更新)。 某些搜索需要有关作者的数据并采用IAuthor对象。 API有一个IAuthor接口和一个实现IAuthor具体类,叫做Author

当作者被标记为小说家时,我需要改变Search.GetBooksByAuthor方法的行为以给出不同的语义。 我听说过开放/封闭原则 ,似乎改变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 } } 

为了知道你的作者是否是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 } } 

或者如前所述,在Author界面中实现一个布尔成员并检查它。 但是上面会阻止你改变你的类结构。

这意味着你的小说家实际上仍然是作家,它只是拥有它自己的类型。 你的方法签名保持不变,你的类结构保持不变你只有一个“不同类型的作者”的类型,理论上应该没问题。 请按以下方式进行测试。

 GetBooks(new Novelist()); 

如何使用谓词进行过滤?

 class Search { public Books[] GetBooks(IAuthor author, Func filter){ // ... } } search.GetBooks(author, a => a.IsNovelist) 

为了扩展类C#.NET在.NET 3.5中引入了扩展方法 ,其主要目的是在不修改现有代码的情况下扩展类:

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

然后你可以正常调用你的Search类:

 Search.GetBooksAsNovelist(author); 

您可以使用C#语言的扩展function。

请参阅http://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx

扩展允许通过保持类完整来向类添加function。

在您的情况下,您可以写为:

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

您可以通过Search对象访问此新方法,Search类也保持不变。

如果您觉得有帮助,请告诉我。

你可以让你的类部分能够添加没有扩展,inheritance或控制反转的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

保持搜索类方法为虚拟,因此任何人都可以覆盖它们创建新行为?