- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我发现了一个提议的 C# 编码标准,其中声明“尝试为所有抽象类提供一个接口(interface)”。有人知道这样做的理由吗?
最佳答案
.NET Framework Design Guidelines 关于接口(interface)和抽象类有一些有趣的说法。
他们特别指出,在 API 的发展方面,接口(interface)的主要缺点是不如类灵活。一旦你发布了一个接口(interface),它的成员就永远固定了,任何添加都会破坏与实现该接口(interface)的现有类型的兼容性。然而,运送一个类(class)提供了更大的灵 active 。可以随时添加成员,即使在初始版本发布之后,只要他们不是抽象的。任何现有的派生类都可以继续不变地工作。以Framework中提供的System.IO.Stream
抽象类为例。它最初不支持超时挂起的 I/O 操作,但 2.0 版能够添加支持此功能的成员,甚至来自现有的子类。
因此,为每个抽象基类提供相应的接口(interface)几乎没有其他好处。该界面不能公开,否则您将在版本控制方面回到原点。而且,如果您只公开抽象基类,那么一开始就拥有接口(interface)几乎没有什么好处。
此外,这一点通常有利于接口(interface),它们允许将契约与实现分开。 Krzysztof Cwalina 认为这种说法是似是而非的:它错误地假设您不能使用类将契约(Contract)与实现分开。通过编写驻留在与其具体实现不同的程序集中的抽象类,很容易实现相同的分离优点。他写道:
I often hear people saying that interfaces specify contracts. I believe this is a dangerous myth. Interfaces, by themselves, do not specify much beyond the syntax required to use an object. The interface-as-contract myth causes people to do the wrong thing when trying to separate contracts from implementation, which is a great engineering practice. Interfaces separate syntax from implementation, which is not that useful, and the myth provides a false sense of doing the right engineering. In reality, the contract is semantics, and these can actually be nicely expressed with some implementation.
一般来说,所提供的指南是DO favour defining classes over interfaces。 Krzysztof 再次评论:
Over the course of the three versions of the .NET Framework, I have talked about this guideline with quite a few developers on our team. Many of them, including those who initially disagreed with the guideline, have said that they regret having shipped some API as an interface. I have not heard of even one case in which somebody regretted that they shipped a class.
第二条准则认为,务必使用抽象类而不是接口(interface)来将契约与实现分离。这里的要点是,正确设计的抽象类仍然允许在契约和实现之间实现与接口(interface)相同程度的解耦。因此,Brian Pepin 的个人观点是:
One thing I've started doing is to actually bake as much contract into my abstract class as possible. For example, I might want to have four overloads to a method where each overload offers an increasingly complex set of parameters. The best way to do this is to provide a nonvirtual implementation of these methods on the abstract class, and have the implementations all route to a protected abstract method that provides the actual implementation. By doing this, you can write all the boring argument-checking logic once. Developers who want to implement your class will thank you.
也许最好的做法是重新审视经常被吹捧的“规则”,即派生类表示与基类的 IS-A 关系,而实现接口(interface)的类具有 与该接口(interface)的 CAN-DO 关系。要提出一个人应该总是编写接口(interface)和抽象基类的代码,而不管这样做的具体原因,似乎没有捕获要点。
关于c# - 接口(interface)/抽象类编码标准,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4790740/
我最近在读 CSAPP。在 10.9 节中,它说标准 I/O 不应该与 socket 一起使用,原因如下: (1) The restrictions of standard I/O Restricti
似乎是一个足够标准的问题,可以保证解决方案中的标准设计: 假设我想在文件中写入 x+2(或更少)个字符串。 x 字符串构成一个部分的内容,这两个字符串构成该部分的页眉和页脚。要注意的是,如果内容中没有
代码版本管理 在项目中,代码的版本管理非常重要。每个需求版本的代码开发在版本控制里都应该经过以下几个步骤。 在master分支中拉取该需求版本的两个分支,一个feature分支,
我有以下sql查询,我需要获取相应的hibernate条件查询 SELECT COUNT(DISTINCT employee_id) FROM erp_hr_payment WHERE payment
所以我正在编写一些代码,并且最近遇到了实现一些 mixin 的需要。我的问题是,设计混音的正确方法是什么?我将使用下面的示例代码来说明我的确切查询。 class Projectile(Movable,
我的环境变量包含如下双引号: $echo $CONNECT_SASL_JAAS_CONFIG org.apache.kafka.common.security.plain.PlainLoginModu
示例: /** * This function will determine whether or not one string starts with another string. * @pa
有没有办法在 Grails 中做一个不区分大小写的 in 子句? 我有这个: "in"("name", filters.tags) 我希望它忽略大小写。我想我可以做一个 sqlRestriction
我搜索了很长时间,以查找将哪些boost库添加到std库中,但是我只找到了一个新库的完整列表(如此处:http://open-std.org/jtc1/sc22/wg21/docs/library_t
我已经通过使用这个肮脏的黑客解决了我的问题: ' Filter managerial functions ActiveSheet.Range("$A$1:$BW$2211").Auto
因此,我很难理解我需要遵循的标准,以便我的 Java 程序能够嵌入 HTML。我是否只需将我的主类扩展到 Applet 类,或者我还需要做更多的事情吗?另外,在我见过的每个 Applet 示例中,它都
我对在 Hibernate 中使用限制有疑问。 我必须创建条件,设置一些限制,然后选择日期字段最大值的记录: Criteria query = session.createCriteria(Stora
我有标准: ICriteria criteria = Session.CreateCriteria() .SetFetchMode("Entity1", FetchMo
我很难编写条件来选择所有子集合或孙集合为空的实体。我可以将这些作为单独的条件来执行,但我无法将其组合成一个条件。 类结构: public class Component { p
@Entity class A { @ManyToMany private List list; ... } @Entity class B { ... } 我想使用条件(不是 sql 查询)从 A
我的数据库中有以下表结构: Table A: Table B: Table C: _______________
请帮助我: 我有下一张 table : 单位 ID 姓名 用户 ID 姓名 利率 单位 ID 用户 ID 我不明白如何从 SQL 创建正确的条件结构: 代码: SELECT * FROM Unit W
我正在构建一个包含项目的网站,每个项目都有一个页面,例如: website.com/book/123 website.com/film/456 website.com/game/789 每个项目都可以
我需要使用两个属性的组合来过滤结果列表。一个简单的 SQL 语句如下所示: SELECT TOP 10 * FROM Person WHERE FirstName + ' ' + LastName L
我有一个“ super 实体”SuperEntity 和三个扩展父类(super class)的实体 ChildEntity1、...、ChildEntity3。 搜索数据库中的所有实体很容易,即我们
我是一名优秀的程序员,十分优秀!