私は最近、TDDとクリーンなコードについて多くのことを読んできましたので、これらを使用する簡単なプロジェクトに取り掛かり、取り組むべき最良のアプローチが本当にわからないことに反対してきました。呼び出し元はコンストラクタを呼び出す前に引数の有効性をチェックする必要がありますか?
Java File
オブジェクトをパラメータとするクラスがありますが、この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");
}
....
}
私は多分オブジェクトを作成するファクトリメソッドを追加し、File
が無効の場合はnullを返す考えました。
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の原則(単一責任、カップリングなど)の面でこれを行うのが好ましい方法ですか?
UPDATE:
は、私は私の現在の状況に適用できるのではなく、一般的に私の質問は、約本当にあったようになり、別の可能性について考え始め、すでに掲載されている答えのいくつかを読みました。
私は呼び出し元のコードの一部としてファイルシステムからのパスを持っており、そのディレクトリ内のすべてのファイルをリストしており、有効かどうかにかかわらずMyObjectコンストラクタに渡すファイルはそれぞれです。 FileFilter
をメソッドlistFiles
に渡すと、listFilesが有効なディレクトリのみを返すことが保証されます。 FileFilter
はMyObjectに内で宣言することができます
public static FileFilter getFilter() {
return new FileFilter() {
public boolean accept(File path) {
return path.isDirectory() && path.getName().startsWith("Prefix");
}
};
}
私のコンストラクタが例外をスローした場合に期待が、それが唯一の有効なディレクトリを渡されているということですので、それは本当に例外的な状況になります。これを行うと、コンストラクタ/ファクトリからチェック例外の必要性を取り除くことができます。これは、例外が予想される動作ではなくどこかのバグを示すためです。しかし、それはコンストラクタかファクトリメソッドのどちらに入れるのかという疑問が残っています。
私にとっては、3番目が好ましいでしょう。短いとあなたは、いくつかのファイルでそれを使用することができます。また、isValidメソッドから新しいオブジェクトを返す必要はなく、isValidがコードの別の部分からtrueを返す場合にのみオブジェクトを作成します。これは、機能を分離するので、良いことです。 –
@AliAlamiriクリーンなコードは、私の好みです。なぜなら、読むことが最も理にかなっています。つまり、何が起こっているのかが読者にはっきりと分かります。私は、発信者が最初にisValidを呼び出すべきであることを認識しなければならないという事実が好きかどうかを判断できません。 – DaveJohnston
ファイルをコンストラクタに渡し、ファイルisValidが存在するかどうか確認してください。これは、オブジェクトを構築するときに呼び出し元からのチェックを隠し、渡されるファイルをコンストラクタでチェックするようにしますか? –