空接口代码有异味吗? [英] Are empty interfaces code smell?

查看:11
本文介绍了空接口代码有异味吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数返回相同类型的对象(查询结果),但没有共同的属性或方法.为了拥有一个通用类型,我使用空接口作为返回类型并在两者上实现".

I have a function that returns same kind of objects (query results) but with no properties or methods in common. In order to have a common type I resorted using an empty interface as a return type and "implemented" that on both.

这听起来当然不对.我只能通过坚持希望有一天这些类会有一些共同点来安慰自己,我会将这些共同的逻辑移到我的空界面中.然而我并不满意,想着我是否应该有两种不同的方法并有条件地调用 next .那会是更好的方法吗?

That doesn't sound right of course. I can only console myself by clinging to hope that someday those classes will have something in common and I will move that common logic to my empty interface. Yet I'm not satisfied and thinking about whether I should have two different methods and conditionally call next. Would that be a better approach?

我还被告知 .NET Framework 使用空接口进行标记.

I've been also told that .NET Framework uses empty interfaces for tagging purposes.

我的问题是:空界面是设计问题的强烈标志还是它被广泛使用?

My question is: is an empty interface a strong sign of a design problem or is it widely used?

编辑:对于那些感兴趣的人,我后来发现函数式语言中的可区分联合是我想要实现的完美解决方案.C# 似乎对这个概念并不友好.

EDIT: For those interested, I later found out that discriminated unions in functional languages are the perfect solution for what I was trying to achieve. C# doesn't seem friendly to that concept yet.

编辑:我写了一篇更长的文章关于这个问题,详细说明问题和解决方案.

EDIT: I wrote a longer piece about this issue, explaining the issue and the solution in detail.

推荐答案

虽然似乎存在针对该用例的设计模式(现在很多人都提到了标记界面"),但我相信这种实践的用法是代码异味的迹象(至少在大多数情况下).

Although it seems there exists a design pattern (a lot have mentioned "marker interface" now) for that use case, i believe that the usage of such a practice is an indication of a code smell (most of the time at least).

正如@V4Vendetta 发布的那样,有一个针对此的静态分析规则:http://msdn.microsoft.com/en-us/library/ms182128(v=VS.100).aspx

As @V4Vendetta posted, there is a static analysis rule that targets this: http://msdn.microsoft.com/en-us/library/ms182128(v=VS.100).aspx

如果您的设计包含需要类型实现的空接口,则您可能将接口用作标记或标识一组类型的方法.如果此标识将在运行时发生,则实现此目的的正确方法是使用自定义属性. 使用该属性的存在与否或该属性的属性来标识目标类型.如果必须在编译时进行识别,那么使用空接口是可以接受的.

If your design includes empty interfaces that types are expected to implement, you are probably using an interface as a marker or a way to identify a group of types. If this identification will occur at run time, the correct way to accomplish this is to use a custom attribute. Use the presence or absence of the attribute, or the properties of the attribute, to identify the target types. If the identification must occur at compile time, then it is acceptable to use an empty interface.

这是引用的 MSDN 推荐:

This is the quoted MSDN recommendation:

删除接口或向其添加成员.如果使用空接口标记一组类型,请使用自定义属性替换该接口.

Remove the interface or add members to it. If the empty interface is being used to label a set of types, replace the interface with a custom attribute.

这也反映了已经发布的维基百科链接的评论部分.

This also reflects the Critique section of the already posted wikipedia link.

标记接口的一个主要问题是接口定义了实现类的契约,并且该契约被所有子类继承.这意味着您不能取消实现"标记.在给出的示例中,如果您创建了一个不想序列化的子类(可能是因为它依赖于瞬态),则必须求助于显式抛出 NotSerializableException(根据 ObjectOutputStream 文档).

A major problem with marker interfaces is that an interface defines a contract for implementing classes, and that contract is inherited by all subclasses. This means that you cannot "unimplement" a marker. In the example given, if you create a subclass that you do not want to serialize (perhaps because it depends on transient state), you must resort to explicitly throwing NotSerializableException (per ObjectOutputStream docs).

这篇关于空接口代码有异味吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆