ファイルとディレクトリの両方を含むファイルシステムをモデル化したいのですが、ディレクトリにはファイルまたは他のディレクトリを含めることができます。
これは私がこれまでに到達したものです:
OOSE book では、同様のモデルが提示されています。
今私は2つの質問があります:
著者が抽象型を表すためにInterfaceを使用しなかったのはなぜでしょうかFileSystemElement?このタイプのインターフェースを使用していませんか?
ご存知のように、ファイルとディレクトリには同様の制約(例:最大256文字)の名前が必要です。したがって、これをFileSystemElementでモデル化するといいでしょう。しかし、インターフェイスは抽象属性を持つことができないので、両方でname属性を繰り返す必要がありますDirectoryおよびFileクラス。この問題のよりよい回避策はありますか?
著者が抽象型FileSystemElementを表すためにインターフェイスを使用しなかったのはなぜでしょうか。このタイプのインターフェースを使用していませんか?
これは、抽象基本クラスを使用する場合と同様に、有効なUMLモデルとしては正しいでしょう。設計の決定は他の要因に依存し、実装言語に結びつくことがよくあります。
しかし、インターフェイスは抽象属性を持つことができないため、DirectoryクラスとFileクラスの両方でname属性を繰り返す必要があります。この問題のより良い回避策はありますか?
インターフェイスは属性を持つことができ、それらは抽象的であると見なされます。これらの抽象属性が実際のコードに変換される方法は、実装言語ごとに異なるイディオムを使用し、多くの場合、同じ実装言語の異なるユーザー間で異なるイディオムを使用します。 UMLレベルでは、それはまったく制限ではありません。
ご存知のように、ファイルとディレクトリには同様の制約(例:最大256文字)の名前が必要です。したがって、これをFileSystemElementでモデル化するといいでしょう。
インターフェースの属性にUML制約を設定できない理由はありません。 { Name.Length <= 256 }
は、他の分類子が所有する属性と同様に、インターフェースが所有する属性に置くことができます。実装方法は、実装言語と実装戦略の両方で異なります。おそらく、インターフェースのインスタンスを取得し、名前を要求して長さをテストする検証関数があるとします。 UML制約のコードへの変換は、「ゲッターを呼び出そうとした場合に例外をスローする」パターンに従うとは限りませんが、多くの場合そうなります。
OOSEブックの作成者がいくつかの実装戦略を念頭に置いていたため、具体的なクラスを使用している可能性があります。私が何をするかは、クラスが他に何のためにあるかに依存します-たとえば、それらがパスフラグメントのプレースホルダーであり、他のものに依存してファイルを開くストリームを作成する場合、それらは完全にテストすることができますモックへのインターフェースなので、余分な抽象化レイヤーを気にしません。ストリームを返す、または他のファイルシステム操作を実行する直接操作があった場合、テスト用にモックできるようにインターフェイスを使用することもできます。どちらも正しくなく、どちらが要件により適しているかは、2つの非常に小さなUML図から決定することはできません。
リンクするOOSEブックをざっと見て、クラス図について同じように話していることを確認します ER-Diagrams オブジェクトではなく名詞間の関係を表すことを検討しますdo。静的な関係にある名詞を検討している場合は、オブジェクト指向の手続き型コードについて話していることになるので注意してください。おそらく、本で提示されているモデルが、操作のインターフェイスではなく属性を持つ具象型に集中していることに気づいているのです。あるいは、異なるタイプの関連を実証しようとしているだけかもしれませんが、それをあまり深く見る価値はありません!
このタイプのインターフェースを使用していませんか?
この場合はインターフェイスを使用しても機能しますが、ディレクトリとファイルの間で動作を複製する必要があります(名前に最大256文字を使用するなど)。 FileSystemElementを抽象クラスにすることをお勧めします(選択した言語がそれをサポートしている場合)。これは、2番目の質問にも答えます。抽象クラスは、その子にデフォルトの動作を提供できます。関連付けられている検証などを使用して、親クラス内でNameプロパティを宣言するだけで済みます。これにより、DirectoryとFileはプロパティと動作を継承します。 Directory of Fileクラスで何かを再定義する必要はありません。コードの重複はありません。
ファイルとディレクトリの関連付けを追加したのが気に入っています(ただし、多重度は指定していません)。今あなたの質問に従って:
著者が抽象型FileSystemElementを表すためにインターフェイスを使用しなかったのはなぜでしょうか。このタイプのインターフェースを使用していませんか?
あなたは正しい、インターフェイスが使用されている可能性があります。ただし、これは最良の選択ではありません。ご存知のように、インターフェイスでは、メソッドに実装コードを追加できません。サブクラス間で共通して見られるメソッドの実装の詳細を含めることができるため、インターフェースの代わりにクラスを使用する方が適切です。この場合、たとえば、nameプロパティの検証を共有することができます。
ご存知のように、ファイルとディレクトリには同様の制約(例:最大256文字)の名前が必要です。したがって、これをFileSystemElementでモデル化するといいでしょう。しかし、インターフェイスは抽象属性を持つことができないため、DirectoryクラスとFileクラスの両方でname属性を繰り返す必要があります。この問題のより良い回避策はありますか?
C#では、インターフェイスの一部として、1つまたは複数のプロパティを定義できます。次に例を示します。
public interface IFileSysElement
{
// Property declaration:
string ElementName
{
get;
set;
}
...
}
ですから、実際には問題ありません。
本のモデルで私が目にする問題は、クラスとサブクラスを関連付けるのが面倒です(私にとって)。考慮すべきもう1つの点は、FileSystemElement名が相対名(たとえば、myFile.txt)であることです。の完全なファイル名を作成または取得するには、別のプロパティまたはメソッドが必要です(例:C:\ Temp\myFile.txt)。これは、いずれかのクラスの「ビジネス識別子」です。
これはコンポジットパターンと呼ばれ、コンポジット(ディレクトリ)とリーフ(ファイル)の間に関連付けはありません。技術的には2つの間の関連付けを示唆していませんが、それは1つのように見えます。