这是Objective-C的类设计问题。这是一个例子:
文件系统有文件和目录。两者都是“节点”。例如,遍历一个目录会产生一个节点列表,其中一些是 [子] 目录,另一些是文件。
这指向类层次结构的以下客户端抽象视图:
@interface Node: NSObject {}
@end
@interface Directory: Node {}
@end
@interface File: Node {}
@end
到目前为止,一切都很好。此时,所有三个类都是抽象的。现在开始实施,您意识到有两种主要途径:使用 URL(Apple 推荐用于 Mac OS X ≥ 10.6)或路径(仅适用于 Mac OS X ≤ 10.5 或Cocotron的可能方式)。
所以现在,你需要为上面的三个抽象类分别开发两个具体的实现:
// Node subclasses
@class NodeWithPath;
@class NodeWithURL;
// Directory subclasses
@class DirectoryWithPath;
@class DirectoryWithURL;
// File subclasses
@class FileWithPath;
@class FileWithURL;
现在考虑,比如说FileWithURL
:
- 它是一个文件,所以它应该继承自
File
. - 它是一个用 URL 实现的节点,所以它应该继承自
NodeWithURL
但是File
和NodeWithURL
不在同一类层次结构行内。如果没有多重继承,就无法在 Objective-C 中表达。
那么你会如何设计这种情况呢?我可以看到两个想法:
- 使用协议,这是一种有限的多重继承形式。
- 使用成员(has-a 而不是 is-a 关系)。
我倾向于支持协议的想法。在这种情况下,Directory
andFile
将是协议,并且六个具体类将从一个公共Node
超类继承并符合它们的对应协议。Node
将有两个子类层次结构:一个使用 URL,一个使用路径。
现在存在对客户端代码隐藏实现的问题。为此,可以使用Node
公共超类设置类集群。客户端代码将获取类型化的对象Node<File>
或Node<Directory>
视情况而定。
任何其他/其他/类似/不同的想法?