このコードの何が問題になっていますか?異なるスコープで削除変数を作成する
-
05-07-2019 - |
質問
最近、以下に概説するコードに似たコードを見ました。
public void someMethod() {
Lecture lect = createLecture();
...
lect.getLectureSeries().delete();
}
public Lecture createLecture() {
LectureSeries series = new Series();
Lecture lect = new Lecture(series);
...
return lect;
}
someMethod()の呼び出しの最後に削除する必要のあるオブジェクト(この場合はLectureSeries)は、実際には別のメソッドの呼び出しで作成されるという点です。最終的に削除されるのと同じスコープで作成する必要がある理由を説明しようとしています。すなわち
public void someMethod() {
LectureSeries series = new Series();
Lecture lect = createLecture(series);
...
series.delete();
}
public Lecture createLecture(LectureSeries series) {
Lecture lect = new Lecture(series);
...
return lect;
}
元のコードは、物事が失敗したときに物事を整理するいくつかの複雑さを引き起こしているので、うまくいけば利点が明白になるでしょうが、このリファクタリングの背後にあるより一般的な原則をどのように説明できるかについて誰にもアイデアがありますか?または誰かが私に間違っている理由を説明したいですか?
==編集==
問題のケースはテストメソッドであったため、テストの実行中に作成されたものをすべてクリーンアップすることが重要でした。 createLecture()の呼び出しの結果として作成されるLectureSeriesの望ましくない副作用は、ほとんどの場合、まだ試して回避すべきものだと思います。
解決
メソッドのスコープを超えて存在するメソッドでオブジェクトを作成することに本質的に問題はありません。
ガベージコレクションされた言語では、調整が自動的に行われます。
プログラマが自分でクリーンアップを管理する必要がある言語では、プログラマはメソッドから受け取るオブジェクトの所有権と、それを解放することに関する義務を理解する必要があります。
他のヒント
「制御の反転」の引数を使用できます。 LectureオブジェクトにはLectureSeriesオブジェクトが必要であり、このオブジェクトを自分で作成するよりも、このオブジェクトを挿入する方が適切です。
依存関係をオブジェクトに注入することは常に良い習慣です。あなたのケースに特有のことですが、ステートメントの作成と削除はできる限り近くすべきだと言うこともできます。これは確かに読みやすさを向上させます。最初のケースでは、アイテムが削除されていますが、アイテムが作成された場所はわかりません。アイテムが作成メソッドで作成されたと推測するか、コード全体を検索して、これが発生する場所を見つける必要があります。エラー処理(LectureSeriesの作成が失敗した場合)も簡単です。