为新行为扩展(而不是更改)搜索类?
我正在更改提供数据的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) { ... } }
结果:
保持搜索类方法为虚拟,因此任何人都可以覆盖它们创建新行为?