编写仅用于集中其他接口的接口是一种良好的做法还是不好的做法?
interface InterfaceA : InterfaceB, InterfaceC {
}
在这样做时,具体实现只需要实现InterfaceA
,这似乎是一件好事,但它不会通过扩展来增加任何价值,这似乎是浪费。
答案 0 :(得分:2)
我认为这取决于你的域名是否有意义。如果有,我会这样做,然后你的程序会更准确地模拟你的域名。
此外,当然,您现在可以编写需要/使用实现InterfaceA
的对象的代码,即两个超级接口的所有方法;以前那是不可能的。
答案 1 :(得分:1)
如果它有意义,并且您将独立使用所有三个接口,那么它肯定是适当的设计决策。
如果事实证明不会使用InterfaceB和IntefaceC,那么只需创建InterfaceA ......
答案 2 :(得分:1)
这对于维护代码可读性确实很有用,然后您可以使用接口A的具体实现,其中需要接口B或C.
答案 3 :(得分:1)
我打算问同样的问题,但我决定保持警惕并做一些广泛的搜索 - 以避免重复。然后我找到了这个 - 我编辑了标题,希望它会变得更受欢迎,因为它应该。
首先,我们应该知道像这样的空接口也称为标记接口 - this other, unanswered, SO discusses concerns marker interfaces和Scott Wisniewsi的回答(目前排名靠前)在考虑我要做的其他事情时很有意思说。
在研究空接口时,您通常偶然发现the MSDN topic concerning Code Analysis warning CA1040,这特别暗示应避免使用至少两个其他接口的空接口。
通过这个标记 - 当然不一定暗示微软的编码指南是事实上的 - 在你的例子中,这正是你正在做的事情(以及我在当前项目中想要做的事情),因此它会通过MS'自己的试金石。因此,我很高兴地说'是的,这样的界面非常合理'。
为了证明理由,我认为一个特别好的例子说明为什么'至少两个接口'开关被置于这个规则上,这与我自己所处的情况类似:
public interface IReadsAResource
{
public byte[] Read(string id);
}
public interface IWritesAResource
{
//returns the id
public string Write(byte[] resource);
}
鉴于这两个接口,我现在可以编写一个明确说明它只需要读或写的组件:
public class NeedsRead
{
private readonly IReadsAResource Reader;
public NeedsRead(IReadsAResource reader){ Reader = reader; }
}
public class NeedsWrite
{
private readonly IWritesAResource Writer;
public NeedsWrite(IWritesAResource writer){ Writer = writer; }
}
我现在通常会选择在单个类ResourceReaderWriter
上实现此接口,因为资源的数据存储将需要两个方法实现共享的依赖项,当任一接口都是需要:
var needsRead = new NeedsRead(new ResourceReaderWriter(/* dependencies */));
var needsWrite = new NeedsWriter(new ResourceReaderWriter(/* dependencies */));
但是如果我有一个类需要同时阅读 和 写资源呢?有了当前的接口生态系统,我需要两个构造函数参数:
public class NeedsReadAndWrite{
public NeedsReadAndWrite(IReadsAResource reader, IWritesAResource writer){
/* reader/writer local variables elided */
}
}
你可能会说,这并不是一件困难,但却造成了两个问题:
任何长期坚持我的人都会看到我现在要去的地方:)
优雅的解决方案是为支持阅读和写作的类型引入接口:
//denotes a component that can both read and write
public interface IReadsAndWritesAResource : IReadsAResource, IWritesAResource
{
}
使用此界面,我们有问题的类型可以重写为
public class NeedsReadAndWrite{
public NeedsReadAndWrite(IReadsAndWritesAResource readerWriter){
/* local variable assignment elided */
}
}
这两个问题现在都是一步一步的。
同样,通过引入读取器和写入器的实例并将读/写调用转发给那些实现此接口的基本代理类型变得简单。
我认为这个例子说明了为什么你会,或者甚至应该,使用将两个或更多其他人聚集在一起的标记接口。