这是一个与Objective-C类设计相关的问题。以下是一个示例:
文件系统有文件和目录。两者都是“节点”。例如,遍历目录会产生一个节点列表,其中一些是[子]目录,其他是文件。
这指向了类层次结构的以下客户端抽象视图:
到目前为止,一切都很顺利。此时,这三个类都是抽象的。现在进入实现阶段,你会发现有两种主要方式:使用URL(适用于Mac OS X≥10.6,由Apple推荐)或路径(仅适用于Mac OS X≤10.5或Cocotron)。因此,现在你需要开发上述每个抽象类的两个具体实现。
现在考虑,比如说
那么你会如何设计这种情况呢?我能想到两个想法:
现在有一个问题是如何隐藏实现细节以防止客户端代码直接访问。可以使用类簇来进行设置,其中
文件系统有文件和目录。两者都是“节点”。例如,遍历目录会产生一个节点列表,其中一些是[子]目录,其他是文件。
这指向了类层次结构的以下客户端抽象视图:
@interface Node: NSObject {}
@end
@interface Directory: Node {}
@end
@interface File: Node {}
@end
到目前为止,一切都很顺利。此时,这三个类都是抽象的。现在进入实现阶段,你会发现有两种主要方式:使用URL(适用于Mac OS X≥10.6,由Apple推荐)或路径(仅适用于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中没有多重继承的方式来表达这个问题。那么你会如何设计这种情况呢?我能想到两个想法:
- 使用协议,它们是多重继承的一种有限形式。
- 使用成员(拥有而不是是关系)。
Directory
和File
将成为协议,并且六个具体的类将从一个共同的Node
超类继承并符合其相应的协议。Node
将有两个子类层次结构:一个使用URL,一个使用路径。现在有一个问题是如何隐藏实现细节以防止客户端代码直接访问。可以使用类簇来进行设置,其中
Node
是通用超类。客户端代码将获得类型为Node<File>
或Node<Directory>
的对象。
是否还有其他/额外/类似/不同的想法?