在开发新代码时,应该使用类助手吗?

10
Delphi 8引入了类助手,用于将VCL/RTL映射到.NET对象层次结构。它们允许向现有类中注入方法,而不需要覆盖类或修改原始类。后续版本的Delphi发现类助手得到了改进,并被移植到Win32。
在帮助文档中,它说“它们不应该被视为开发新代码时使用的设计工具。”
类助手违反了传统的面向对象编程,但我不认为这使它们成为一件坏事。这个警告是否有必要?
在开发新代码时,应该使用类助手吗?你在开发新代码时使用它们吗?为什么或为什么不?
根据Malcolm's comments的评论:新代码意味着每天应用程序开发,在其中您拥有一些第三方库、一些现有代码,以及您正在编写的代码。
10个回答

15

关键是要看你所谓的“新代码”是什么意思。

对于新开发的类来说,它们并不是相关的,所以在这种情况下,不应该使用它们。

但即使在全新的项目中,你可能仍然需要修改一个现有的类,而无法通过其他方式进行更改(vcl类,第三方类等)。在这种情况下,我认为可以使用。

它们本身并不是邪恶的。像大多数其他事物一样,你只需要了解它们的工作原理,在适当的上下文中使用它们。


1
您总是可以选择其他选项,例如装饰器和适配器模式等。 - Vegar

8
在将类助手作为新的炫酷代码工具之前,我认为您需要了解它所包含的限制。每个类只能提供一个类助手。那么,如果您为自己的类提供类助手,并且您的类派生自其他人已经为其提供了类助手的公共类呢?
CodeGear将类助手引入为“hack”以防止破坏事物,而不是作为一种很酷的设计特性。在设计代码时,请不要使用类助手,我知道您可以做到。在处理您可以控制的现有代码时,请使用重构。当没有其他方法时,请使用类助手。
这是我的意见...

6

Microsoft在LINQ中大量使用了扩展方法。因此,如果使用类助手可以改善您的代码,您应该在新代码中使用它们。请参见什么是类助手的好用途?以获取一些好的用途。


2
.NET扩展方法不像类助手那样受限制。如果所有的LINQ支持都会因此崩溃,你也不会建议在.NET中使用扩展方法,对吧?每个类只能有一个类助手。如果你定义了一个,它将破坏任何现有的类助手。 - Vegar

3

我经常使用它们。我使用远程对象和由RO引擎创建的对象,因此您不能在不从它们下降然后进行其他操作的情况下添加到它们中。类助手意味着我可以像处理任何其他对象一样处理它们。虽然一个类只能有一个帮助程序,但您可以下降帮助程序类,以便获得继承的行为。


所以,如果你不能派生,就使用一个类助手。如果已经有一个类助手,那么你就从它派生。如果你不能从它派生呢?你会为这个类助手制作另一个类助手吗...? - Vegar
我以完全相同的方式在自动生成的RemObjects SDK单元中使用类助手。 - norgepaul

2

抱歉,我必须明确一点:如果内部的Delphi人员自己声称“它们不应被视为在开发新代码时使用的设计工具”,那么根据定义,它们不应该被使用。它们只用于扩展VCL以满足他们自己的目的。谁比编写它的人更能给出更好的理由呢?


我认为真正的问题是“为什么”,而“因为我告诉你不要这样做”很少能作为一个答案——相信我,我有孩子。 :-) - tvanfosson
@DarianMiller 你说得很好。也许我的问题更好的陈述方式是“是否应该更新文档以删除警告……” - Jim McKeeth
1
我也有孩子。即使他们想要把你的“因为”当做答案,你也不能停止警告。 - Vegar

2

我同意Vegar的观点:类助手是一种紧急工具。当你知道它们是在规定时间内完成任务的唯一方式时,可以使用它们。稍后,如果有时间,就可以将它们删除。

曾经有一次,我忘记了一个参数设置,如果Delphi 2006中不存在类助手,将花费大量的时间......有了类助手,只需要6个小时来让事情正常运作。但是,这是一种紧急情况 - 类助手是一种模糊的语言特性,对于新开发者来说,跟随程序的流程会造成困难。


2
也许你可以采用一个好的方法(像我一样):
  1. 始终优先考虑继承而不是使用类助手,在无法使用继承时才使用它们。
  2. 优先考虑使用类助手而不是裸露的全局方法
  3. 如果你需要在多个单元中使用扩展功能,请尝试其他方法(例如类包装器)。
.Net扩展方法非常相似,它们被创建和支持的原因完全相同:对基类进行扩展(而不是升级,这在Delphi.Net中不是一种选择,为了尝试使Delphi本地代码与.Net代码“兼容”-在我看来,这太过雄心壮志)
无论如何,Delphi类助手仍然是某些情况下非常有用的工具

1

这些听起来像是C#扩展方法。我会说,虽然这样的扩展方法在你没有能力修改需要扩展功能的类时很有用,但它们并不是设计自己代码的好方法。在设计自己的代码时,你希望所有功能尽可能地位于同一个代码文件中,而不是分散在不同的类中。我会建议将它们用于它们的预期用途--作为装饰器来向封闭类添加新功能--而不要在设计自己的代码时使用它们。


是的,我认为C#扩展方法是基于类助手的。 - Jim McKeeth
确实是这样 - 我们拥有这个想法的专利。;-) - Nick Hodges
我在PDC2005时与Anders交谈,当时他基本上确认它们是其扩展。 - Jim McKeeth

1

我发现自己越来越多地将它们用作设计构造。

我使用它们的情况:

  • 在客户端/服务器设置中,我使用类助手扩展共享基类,以提供仅限于服务器或客户端的功能。
  • 使用助手来补充 VCL/RTL 类(和其他第三方代码)的便捷工具函数。
  • 解决类不共享相同继承树时的差异(例如使用助手使得拥有通用的 Count 和 Items 属性成为可能)。

事实上,我希望 Delphi 能够接受同一基类的多个助手 - 如果我记得正确的话,我甚至已经提交了这个请求。


1

我觉得这篇文章非常有意思。它讨论了C++,但主要思想是独立于语言的。主要观点是在面向对象的环境中,全局程序有时比方法更可取。从这个角度来看,类帮助程序的需求会减少。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接