ロバートC.マーティンのクリーンコード:アジャイルソフトウェアクラフトマンシップのハンドブックの45ページに、マーティンは出力引数は避けるべきであると書いています。 「出力引数」の意味と、それらを回避する必要がある理由を理解できません。
Martinの出力引数appendFooter(s);
の例は、関数public void appendFooter(StringBuffer report)
を呼び出します。彼のコードの改善はreport.appendFooter();
です
コードコンテキストの不足が原因である可能性がありますが、出力引数の使用が不適切なコーディングであると見なされているかどうかはわかりません。誰かが概念を説明したり、これを理解するためのコードの追加の例を挙げたりできますか?
次の関数も、上記の原則によって不明瞭なコードの例と見なされますか?
int[] numberArray = {3, 5, 7, 1};
sortArray(numberArray);
上記が出力引数を使用しないというマーティンの原則に違反する場合、配列をフィールドとして持つオブジェクトと、配列をソートするために呼び出すことができる関数を用意する方が良いでしょうか?
ObjectWithArrayField numberArray = new ObjectWithArrayField(3, 5, 7, 1);
numberArray.sort();
ボブ・マーティンは単に読みやすさについて話しているだけです。
appendFooter
の例の問題は、プログラムのどこかにコード行appendFooter(s)
がある場合、その呼び出しがs
をinputそしてそれをどこかに追加するか、またはs
が単に渡されてoutputその関数の。確かに、関数のドキュメントを確認する必要があります。ただし、report.appendFooter()
のような呼び出しは、その問題を回避します。何が起こるかがより明確になります。
ただし、ボブ・マーティンは「出力引数を決して使用しない」とは言っていないことに注意してください。「コードをもう少しきれいに保つのに役立つので、一般的には使用しないでください」と述べています。したがって、これは盲目的に実行する必要がある頭の悪いカーゴカルト規則ではありません。
標準配列とコレクションのSort
メソッドは少し異なります。 sort
メソッドを各標準配列データ型のメンバー関数にすると、言語設計者の観点からいくつかの欠点が生じます。たとえば、Array.sort
のようなメソッドを使用すると、これを標準ライブラリに保持できます、Javaランタイムの外。ただし、時々ソートする必要がある個々のコレクション型を作成する場合、sort
をメンバー関数として追加することは、それを別のクラスに入れます。
これは、関数から値を返すために予期しないメカニズムを使用することの問題です。これは通常、関数で実行しすぎた、または責任の不一致が原因です。はるかに、関数の結果を伝える最良の方法は、戻り値を使用することです。それが自明であることを願っています。オブジェクト指向言語では、2番目に良い方法はオブジェクトを変更することです。
これら2つのオプションの間には、関数の結果を伝える明確で明白な方法がたくさんあるので、唯一の手段として引数を変更したい場合は、アーキテクチャで何かがおかしくなっています。クラスの責任を再配置して、変更を行う人が最初にデータを所有するようにする必要があります。
1つの例外は、非常に一般的なアルゴリズムです。たとえば、パブリックインターフェースを使用して任意のタイプのコンテナーに一般的に適用できる場合、ソートアルゴリズムは、それがソートするコンテナーとは正しく分離する可能性があります。ワンショットappendFooter
関数にはその言い訳はありません。