问题标签 [marker-interfaces]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - Java中标记接口的用途是什么?
当在标记接口中没有什么要实现的Serializable
时候,实现它有什么用?
.net - 使用标记接口而不是属性的令人信服的理由
之前在 Stack Overflow 上讨论过,我们应该更喜欢属性而不是标记接口(没有任何成员的接口)。MSDN 上的界面设计文章也提出了这个建议:
避免使用标记接口(没有成员的接口)。
自定义属性提供了一种标记类型的方法。有关自定义属性的更多信息,请参阅编写自定义属性。当您可以将属性检查推迟到代码执行时,自定义属性是首选。如果您的方案需要编译时检查,则您不能遵守此指南。
甚至还有一个FxCop 规则来强制执行此建议:
避免空接口
接口定义了提供行为或使用契约的成员。接口描述的功能可以被任何类型采用,无论该类型出现在继承层次结构中的什么位置。类型通过为接口的成员提供实现来实现接口。空接口没有定义任何成员,因此也没有定义可以实现的合约。
如果您的设计包含类型预期实现的空接口,则您可能正在使用接口作为标记,或者是标识一组类型的一种方式。如果此标识将在运行时发生,则完成此操作的正确方法是使用自定义属性。使用属性的存在与否或属性的属性来识别目标类型。如果必须在编译时进行识别,那么使用空接口是可以接受的。
该文章仅说明了您可能会忽略警告的一个原因:当您需要类型的编译时标识时。(这与界面设计文章一致)。
如果接口用于在编译时识别一组类型,则从该规则中排除警告是安全的。
真正的问题来了:微软在框架类库的设计中没有遵循他们自己的建议(至少在几个情况下):IRequiresSessionState 接口和IReadOnlySessionState 接口。ASP.NET 框架使用这些接口来检查它是否应该为特定处理程序启用会话状态。显然,它不用于类型的编译时识别。为什么他们不这样做?我可以想到两个潜在的原因:
微优化:检查对象是否实现接口(
obj is IReadOnlySessionState
)比使用反射检查属性(type.IsDefined(typeof(SessionStateAttribute), true)
)更快。大多数情况下,这种差异可以忽略不计,但它实际上可能对 ASP.NET 运行时中的性能关键代码路径很重要。但是,他们可以使用一些变通方法,例如为每个处理程序类型缓存结果。有趣的是,ASMX Web 服务(具有相似的性能特征)实际上为此目的使用了EnableSession
属性的WebMethod
属性。与使用第三方 .NET 语言的属性修饰类型相比,实现接口可能更受支持。由于 ASP.NET 被设计为与语言无关,并且 ASP.NET 为基于指令属性实现所述接口的类型(可能在CodeDom的帮助下使用第三方语言)生成代码,它可能会产生更多感觉使用接口而不是属性。
EnableSessionState
<%@ Page %>
使用标记接口而不是属性的有说服力的理由是什么?
这仅仅是一个(过早的?)优化还是框架设计中的一个小错误?(他们认为反射是一个“红眼睛的大怪物”吗?)想法?
java - 组合和标记接口是否有解决方法?
我看到自己经常遇到以下问题。我有某种标记接口(为简单起见,让我们使用java.io.Serializable
)和几个包装器(适配器、装饰器、代理......)。但是,当您将 Serializable 实例包装在另一个实例(不可序列化)中时,您会失去功能。可以通过 List 实现实现的 java.util.RandomAccess 也会出现同样的问题。有没有很好的 OOP 方式来处理它?
java - 为什么是java注解?
我想问为什么这么多使用java注解...我知道它们替换了例如jpa中的xml配置,但是为什么要使用这种配置呢?考虑这段代码:
在,当我尝试将其置于持久性上下文中时,使用EntityManager
'spersist 方法,尝试持久化NonEnt
实例时出现运行时错误(最好是编译错误)。对我来说有一个明显的解决方案,强制实体实现一些无方法接口而不是使用@Annotations。但这在框架设计师中并不流行,这种解决方案的缺点是什么?谢谢回答...
c# - 如何命名使用属性的类?
我正在编写自定义属性而不是标记接口
我不能像这样编写字典吗?
避免标记接口,我正在尝试使用自定义属性。为什么我不能写上面的代码?
c# - C#中的匿名标记接口?
我想知道是否可以在 C# 中本地创建标记接口,例如在 foreach 循环中。
考虑我们有应该调用其 HandleInput- 和 Update- 方法的游戏组件。这些方法分别定义在相应的接口 IUpdateable 和 IInputHandler 中。我们当然可以像这样进行常规的 foreach 循环:
但是,如果有一种方法可以指定迭代变量的类型是由 IUpdateable 和 IInputHandler 构成的临时标记接口,那将是非常简洁的:
这可能吗,会更好吗?我个人认为它很优雅。// 谢谢,菲利普·希尔德
domain-driven-design - 实施 Udi 的获取策略 - 我如何搜索?
背景
Udi Dahan 建议将获取策略作为用于数据访问的有用模式。我同意。
这个概念是使角色明确。例如,我有一个聚合根 - 客户。我希望客户在我的应用程序的几个部分中 - 可供选择的客户列表,客户详细信息的视图,并且我想要一个按钮来停用客户。
似乎 Udi 会为这些角色中的每一个建议一个界面。所以我有ICustomerInList
非常基本的细节,ICustomerDetail
其中包括最近购买的 10 种产品,并且IDeactivateCustomer
有一种方法可以停用客户。每个接口都暴露了我的客户聚合根,以便在每种情况下完成工作。我的客户聚合根实现了所有这些接口。
现在我想为每个角色实现一个获取策略。每种策略都可以将不同数量的数据加载到我的聚合根中,因为它将位于只公开所需信息位的接口后面。
实现这部分的一般方法是询问服务定位器或其他样式的依赖注入。例如,此代码将获取您想要的接口ICustomerInList
,并找到一个获取策略来加载它(IStrategyForFetching<ICustomerInList>
)。这个策略是由一个类实现的,该类知道只加载具有 ICustomerInList 接口所需的信息位的客户。
到目前为止,一切都很好。
问题
您传递给服务定位器或IStrategyForFetching<ICustomerInList>
. 我看到的所有示例都仅通过已知 ID 选择一个对象。这种情况很简单,调用代码通过这个id,会得到具体的接口。
如果我想搜索怎么办?或者我想要客户列表的第 2 页?现在我想传递更多获取策略所需的术语。
可能的解决方案
我见过的一些示例使用谓词 - 如果特定聚合根应该是结果集的一部分,则返回 true 或 false 的表达式。这在条件下工作得很好,但是让前 n 个客户回来而不是更多呢?或者获取搜索结果的第 2 页?或者结果如何排序?
我的第一反应是开始向我的IStrategyForFetching<ICustomerInList>
It now添加泛型参数IStrategyForFetching<TAggregateRoot, TStrategyForSelecting, TStrategyForOrdering>
。这很快变得复杂而丑陋。不同的存储库使情况更加复杂。一些存储库仅在使用特定策略进行选择时提供数据,有些仅提供某些类型的排序。我希望能够灵活地实现可以采用排序功能的通用存储库以及仅返回以特定方式排序的聚合根的专用存储库。
听起来我应该应用开始时使用的相同模式 - 如何明确角色?我是否应该使用有效负载 Y(搜索/排序参数)实施获取 X(聚合根)的策略?
编辑 (2012-03-05)
如果我不是每次都返回聚合根,这一切仍然有效。如果每个接口由不同的 DTO 实现,我仍然可以使用 IStrategyForFetching。这就是这种模式强大的原因 - 获取和返回的内容不必以任何方式映射到聚合根。
我最终使用了IStrategyForFetching<TEntity, TSpecification>
. TEntity 是我想要得到的东西,TSpecification 是我想要得到它的方式。
c# - c#中的标记接口
我目前正在尝试在 c# 中实现标记接口。但是到目前为止我还没有这样做,所以我想请教您。
简短我的问题:
我有一个接口工厂,工厂包含几个子接口,它们应该是标记接口,因为它们没有属性或方法或其他东西。所以标记接口应该实现接口工厂。我的标记接口是例如汽车、卡车等。标记接口是为 MyBMW、MyAUDI 等的汽车实现的。我怎样才能实现这样的模式?谢谢!
.net - 我应该使用标记接口吗?
我有一个具有许多属性的类,其中一个是对象,我们称它为 ExtraData。这可以是三种不同类型中的任何一种的对象,这三种类型之间没有共享字段。
我应该创建一个所有三个对象类都实现的标记接口并使 ExtraData 属性属于该接口类型吗?我读过的所有内容都说要在 .NET 中避免这种情况,并尽可能使用自定义属性。如果我这样做,我会让 ExtraData 成为一个简单的对象并检查属性以确定它的类型吗?如果我想使用这些数据、检查属性并相应地进行转换,这似乎需要做很多额外的工作。
这是“不使用标记接口”规则的例外吗?还是我错过了一些明显的东西?
谢谢。