私は最近、TDD とクリーン コードについてよく読んでいるので、これらを使用する単純なプロジェクトに取り組み始めました。
JavaFile
オブジェクトをパラメーターとして受け取るクラスがあります。このFile
オブジェクトはディレクトリである必要があり、特定のプレフィックスで始まる必要があります。私の最初のパス スルーではFile
、コンストラクターを呼び出す前にオブジェクトのチェックを行いました。つまり、オブジェクトがディレクトリであることをチェックし、名前が有効であることをチェックしました。しかし、それを有効にするもの、特に有効なプレフィックスを指定しているのは呼び出し元であることが好きではありません。このロジックはクラス自体に配置する必要があると思います。
コンストラクターでこのチェックを行い、有効でない場合は例外をスローすることもできますが、問題の性質を考えると、 のリストを反復処理しているFile
場合、それらの一部が「有効ではない」ことが完全に予想されます' (つまり、それらはディレクトリではなくファイルになります) では、スローすることはException
本当に保証されていますか?
public MyObject(File directory) {
if (!directory.isDirectory()) {
throw new IllegalArgumentException("Must be a directory");
}
if (!directory.getName().startsWith("Prefix")) {
throw new IllegalArgumentException("Must start with Prefix");
}
....
}
Factory メソッドを追加してオブジェクトを作成し、無効な場合は null を返すことを考えましたFile
。
public static MyObject createMyObject(File directory) {
if (!directory.isDirectory() || !directory.getName().startsWith("Prefix")) {
return null;
}
return new MyObject(directory);
}
別の方法として、コンストラクターを呼び出す前に、呼び出し元のファイルを検証するクラスに静的メソッドを追加することを考えました。
public static boolean isValid(File directory) {
return directory.isDirectory() && directory.getName().startsWith("Prefix");
}
if (MyObject.isValid(directory)) {
MyObject object = new MyObject(directory);
}
では、クリーンなコードとすべての OOP 原則 (単一の責任、結合など) に関して、これを行うための好ましい方法はどれでしょうか?
アップデート:
すでに投稿された回答のいくつかを読んだ後、私の質問が実際にあったので、一般的にではなく、私の現在の状況にのみ適用できる別の可能性について考え始めました.
呼び出しコードの一部として、ファイルシステムからのパスがあり、そのディレクトリ内のすべてのファイルをリストしています。有効かどうかに関係なく、MyObject コンストラクターに渡すのは各ファイルです。listFiles が有効なディレクトリのみを返すことを保証するFileFilter
メソッドに を渡すことができます。MyObject 内で宣言できますlistFiles
。FileFilter
public static FileFilter getFilter() {
return new FileFilter() {
public boolean accept(File path) {
return path.isDirectory() && path.getName().startsWith("Prefix");
}
};
}
コンストラクターが例外をスローした場合、有効なディレクトリのみが渡されることが期待されるため、実際には例外的な状況になります。これを行うと、コンストラクター/ファクトリーからチェック済み例外の必要性を取り除くことができるということになります。しかし、それをコンストラクターに入れるか、ファクトリー・メソッドに入れるかという問題はまだ残っています。