实现多个接口的类的清晰度(替代委托):
假设我们有以下内容:
IFirst = Interface(IUnknown)
function GetStuff: Integer;
end;
ISecond = Interface(IUnknown)
function GetOtherStuff: Integer;
end;
TFirstSecond = class(TInterfacedObject, IFirst, ISecond)
private
function GetStuff: Integer; //implementation of IFirst
function GetOtherStuff: Integer; //implementation of ISecond;
end;
我从来不喜欢这样一个事实:在 TInterfacedObject 中似乎无法区分哪些方法实现哪些接口。我错过了什么吗?有谁知道如何构造代码来做到这一点?指定GetStuff
是IFirst
的实现,而GetOtherStuff
是ISecond
的实现? (“发表评论”不是我正在寻找的答案...)
我知道我可以使用“implements”指令为每个接口在 TFirstSecond
中定义属性并将实现委托给实例包含在 TFirstSecond
中,从而隔离一切。但我想要一条捷径...
Let's say we've got the following:
IFirst = Interface(IUnknown)
function GetStuff: Integer;
end;
ISecond = Interface(IUnknown)
function GetOtherStuff: Integer;
end;
TFirstSecond = class(TInterfacedObject, IFirst, ISecond)
private
function GetStuff: Integer; //implementation of IFirst
function GetOtherStuff: Integer; //implementation of ISecond;
end;
I have never liked the fact that in TInterfacedObject
there seems to be no way to distinguish between which methods implement which interfaces. Am I missing something? Does anyone know a way structure the code to do that? To designate that GetStuff
is the implementation of IFirst
and GetOtherStuff
is the implementation of ISecond
? ('Put a comment' is not the answer I'm looking for...)
I know I can use the 'implements' directive to define properties in TFirstSecond
for each interface and delegate the implementations to instances contained within TFirstSecond
, thereby segregating everything. But I'd like a shortcut...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我想您在不使用注释的情况下真正可以做的唯一一件事就是添加方法解析子句:
我不'我认为这确实增加了很多混合,我个人认为这比没有方法解析子句更糟糕。
I suppose the only thing you can really do without using comments is to add method resolution clauses:
I don't think this really adds very much to the mix, and I personally would consider this worse than without the method resolution clauses.
在您发布的情况下,我也更喜欢评论(接口名称就像 NGLN 所说的那样),但我想解释为什么 implements 关键字在其他一些情况下可能是最佳解决方案,但不是在在简单的情况下,每个接口只有一种方法,就像您的简单示例一样。
我知道你说过你了解 Implements;但对于那些还没有看过它的人来说,我想记录一下它何时有用,请耐心等待。在某些情况下,开设更多课程的所有额外工作甚至是值得的。
因此,我不会使用实现作为快捷方式(如您所见,它更长!),而是仅当每个接口涉及 100 个要实现的方法,并且最终的设计具有更少的耦合、更好的内聚性和可读性时。
所以这确实是一个愚蠢的例子,但是如果 IFirst 和 ISecond 中的每一个都有 100 个方法,那么这可能是一个巨大的飞跃......
你可以说 Implements 是我们可以做“部分类”的唯一方法,或者至少创建一个复合类,它实现了一堆接口,并且有一堆子属性(受保护的甚至可能是私有的)用于执行“实现”委托。如果您将其他所有内容都从包含聚合类的单元中移出,那么您可能会得到一个非常干净的设计。
In the case you post, I prefer comments (interface name just as NGLN puts it) too, but I would like to explain why the implements keyword can be the best solution in some other cases, just not in trivial cases where there's only one method per interface as in your trivial sample.
I know you said you know about Implements; but for people coming along who have not seen it, I'd like to document when it IS useful, bear with me. It is even worthwhile having all the extra work of having more classes, in some cases.
So I would use implements not as a shortcut (as you see it's longer!) but only when each interface involves 100 methods to be implemented, and where the resulting design has less coupling, and better cohesion and readability only.
So this is an admittedly silly example, but if each of IFirst and ISecond had 100 methods, then it might be a great leap forward...
You could say Implements is the only way we could do "partial classes", or at least create one composite class that implements a bunch of interfaces, and have a bunch of sub-properties (which are protected or perhaps even private) used to do the "implements" delegation. If you move everything else right out of the unit that contains the aggregating class, you could have a really clean design.
虽然您特别要求不涉及注释的答案,但我可以说使用注释是不仅仅是 Delphi VCL 的常见解决方案,准确地说如下:
Although you are specifically asking for an answer not involving comments, may I say that using comments is the common solution by more then just the Delphi VCL, as follows to be precise:
D2006(但也可能是更早的版本,D2006 只是我目前可用的最早的版本),支持接口方法到特定类函数的“映射”。这消除了像使用
implements
关键字那样拥有属性的必要性。当两个接口包含相同的方法签名但需要不同的实现时,使用接口映射也应该是消除歧义的一种方法。
示例:
如果您有大量接口或大量方法,则缺点是:重复。但是,正如您在示例中看到的,您不需要为接口中的所有方法指定映射。
出于文档目的,您可以将映射直接与实际方法声明放在一起,这样它们就可以保持在一起并且不太可能不同步(或者更确切地说,映射将错过新方法,因为您不需要为每个方法声明一个映射)接口方法):
D2006 (but probably earlier versions as well, D2006 is just the earliest I have available at the moment), supports "mapping" of interface methods to specific class functions. This gets rid of the necessity to have a property as you do with the
implements
keyword.Using interface mapping should also be a way to remove ambiguity when two interfaces contain the same method signature but need different implementations.
Example:
Drawback if you have lots of interfaces or lots of methods: repetition. However, as you can see in the example, you do not need to specify mappings for all methods in an interface.
For documentation purposes you could put the mapping directly with the actual method declaration, so they stay together and are less likely to get out of sync (or rather that the mappings will miss new methods, as you do not need to declare a mapping for each interface method):