你会拥有太多的“受保护的虚拟”方法吗?

Posted

技术标签:

【中文标题】你会拥有太多的“受保护的虚拟”方法吗?【英文标题】:Can you ever have too many "protected virtual" methods? 【发布时间】:2010-09-24 01:50:57 【问题描述】:

这是为那些在大型项目和 API/框架设计方面有经验的人准备的问题。

我正在开发一个将来会被许多其他项目使用的框架,所以我想让它变得漂亮和可扩展,但同时它需要简单易懂。

我知道很多人抱怨 .NET 框架包含太多的密封类和私有成员。我应该避免这种批评,并用大量受保护的虚拟成员打开我所有的课程吗?

让尽可能多的方法和属性受保护虚拟是个好主意吗?在什么情况下你会避免受保护的虚拟并将成员设为私有。

【问题讨论】:

【参考方案1】:

您的类包括数据成员;对那些功能永远不应该改变的数据成员执行基本内部操作的方法应该始终是私有的。因此,对数据成员进行基本操作(例如初始化和分配)的方法应该是私有的。否则,您将面临“二阶”派生类启用不完整行为集的风险;一阶导数成员可能会重新定义类的行为。

话虽如此,我认为您在将方法定义为“受保护的虚拟”时应该非常小心。我会非常谨慎地将方法定义为“受保护的虚拟”,因为这样做不仅声明了覆盖功能的可能性,而且在某些方面定义了覆盖的期望功能。在我看来,这听起来像是一组定义不足的行为。我宁愿有一套明确定义的行为来覆盖。如果您想拥有大量可覆盖的行为,我宁愿研究面向方面的编程,它以非常结构化的方式允许这种事情。

【讨论】:

【参考方案2】:

当您使用单词 virtual 标记方法时,您就是在允许用户更改该部分逻辑的执行方式。出于许多目的,这正是您想要的。我相信你已经知道了。

但是,应该为这种扩展设计类型。你必须主动选择方法,让用户改变行为是有意义的。如果您只是在所有地方都使用 virtual ,则可能会破坏类型的完整性,它并不能真正帮助用户理解类型,并且您可能会引入许多错误,包括与安全相关的问题。

我更喜欢保守的方法。我用sealed 标记我的所有类,除非我特别想启用继承,并且在那些(少数)情况下,我只将所需的方法设为虚拟。

如果将来需要更改类以允许继承,则可以轻松删除 sealed 标记。但是,如果您想更改一个已经被用作其他类型的基类的类,则在更改基类时可能会破坏子类。

【讨论】:

【参考方案3】:

我的观点是:

如果您可以使用events,则首选protected 方法。 尽量避免使用protected 方法,如果不可能,则必须使用它;-)。

【讨论】:

【参考方案4】:

选择protected 而不是private 是经过深思熟虑的设计决定。您是在声明您的类明确支持使用该功能,以及随之而来的所有开销(设计和实现工作)。我只会在我知道有必要的情况下使用protected,主要是因为我自己在做。 (您还可以从 BCL 开发人员那里找到与我所说的内容相同的 cmets。)

virtual/non-virtual 的性能差异与任何强大到足以运行 .NET Framework 的机器无关。

【讨论】:

【参考方案5】:

不,你不能有“太多”。然而,我们应该不惜一切代价使每个受保护而不是私有或避免“密封”的想法是愚蠢的。我会将“辅助方法”和内部数据结构保密。

【讨论】:

【参考方案6】:

尽可能多地创建我的方法和属性protected virtual 是个好主意吗?

不是个好主意。

受保护的虚拟方法在框架中提供扩展点,同时增加耦合。

有更多有前途的技术可以提供可扩展性:Composition 和 Delegation。

【讨论】:

以上是关于你会拥有太多的“受保护的虚拟”方法吗?的主要内容,如果未能解决你的问题,请参考以下文章

这。与基地。对于继承的受保护的非虚拟方法?

C#状态模式和事件

函数参数太多的一种简化方法

太多的左连接是代码味道吗?

虚拟化之lxc

怎样设定目标——设定目标失败的七大原因