これは、Objective-C を使用したクラス設計の問題です。以下に例を示します。
ファイル システムには、ファイルとディレクトリがあります。どちらも「ノード」です。たとえば、ディレクトリをたどると、ノードのリストが生成されます。一部は [サブ] ディレクトリで、他はファイルです。
これは、クラス階層の次のクライアント側抽象ビューを指します。
@interface Node: NSObject {}
@end
@interface Directory: Node {}
@end
@interface File: Node {}
@end
ここまでは順調ですね。この時点で、3 つのクラスはすべて抽象クラスです。実装に進むと、2 つの主要なルートがあることがわかります: URL を使用する (Mac OS X ≥ 10.6 では Apple が推奨)、またはパス (Mac OS X ≤ 10.5 またはCocotronでのみ可能な方法)。
したがって、上記の 3 つの抽象クラスのそれぞれの 2 つの具体的な実装を開発する必要があります。
// 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 でそれを表現する方法はありません。
では、この状況をどのように設計しますか? 私は2つのアイデアを見ることができます:
- 多重継承の制限された形式であるプロトコルを使用します。
- メンバーを使用します (is-a 関係ではなく has-a 関係)。
私はプロトコルのアイデアを好む傾向があります。その場合、Directory
とFile
はプロトコルになり、6 つの具体的なクラスは共通のスーパークラスから継承されNode
、対応するプロトコルに準拠します。Node
1 つは URL を使用し、もう 1 つはパスを使用します。
ここで、実装をクライアント コードから隠すという問題があります。Node
クラス クラスタは、共通のスーパークラスを使用してこの目的のために設定できます。Node<File>
クライアント コードは、場合に応じて型付けされたオブジェクトを取得しますNode<Directory>
。
追加/その他/類似/異なるアイデアはありますか?