副作用が読み込まれたこの長いJavaコードのメソッドをより純粋なバージョンにリファクタリングするにはどうすればよいですか?オプションで純粋な関数で副作用を呼び出す
public Result nonPureMethod(String param1, String param2){
this.current_status = "running";
String s1 = step1(param1, param2);
this.logger.log("About to do step 2, this could take while");
String s2 = step2(s1);
this.logger.log("Completed step 2");
String s3 = step3(s2);
this.notifyOtherObject(s3);
if (this.UserPressedEmergencyStop){ this.current_status = "stopped"; return; }
String s4 = step4(s3);
this.current_status = "completed";
this.saveFile(s4);
return new Result(s4);
}
これらの副作用はすべて実行する必要があります。しかし、時々私はこのようになりますこの方法、の「純粋な」バージョンを呼び出したい:
public static Result pureMethod(String param1, String param2){
String s1 = step1(param1, param2);
String s2 = step2(s1);
String s3 = step3(s2);
String s4 = step4(s3);
return new Result(s4);
}
注:私は2つのメソッドを維持する必要はありません。可能であれば、私は1つ持っていたい。また、私はオプションでロギングのようないくつかの副作用を持つことができたいと思っていますが、他にはありません。このコードをリファクタリングする最良の方法は何ですか、私はそれを呼び出すことができ、オプションで副作用を持つことがあります。
私は現在Java 8を使用していますが、この問題はかなり一般的だと思います。私はこれまでに2つのアプローチを考えて問題を解決しました。まず、メソッドにブール値を渡すことができます: "runSideEffects"。 falseの場合は、副作用を実行するコードをスキップします。別のより柔軟なソリューションは、パラメータとして渡されるラムダ関数を要求し、副作用を呼び出す代わりにそれらを呼び出すことによって関数を変更することです。たとえば、 "void log(String msg)"のようなメソッドをパラメータとして渡すことができます。メソッドのプロダクション呼び出しは、メッセージをロガーに書き込む関数を渡すことができます。他の呼び出しは、log(msg)が呼び出されたときに効果的に何もしないメソッドを渡すことができます。これらのソリューションのどちらも素晴らしいとは思わないので、コミュニティに提案を求めています。
のJava 8の新しいものが本当にこの方法であなたを助けるところ、私は表示されません。あなたが示唆しているのは、副作用と副作用=戦略の関係がない、大まかには(stragegyパターン)(https://en.wikipedia.org/wiki/Strategy_pattern)です。それはあなたがいつもやっていたことかもしれません(と私はそれがあなたのコードを改善するだろうと想像することはできません) – zapl
2つの実装を持つことは間違いなく(@zaplによって提案されるように)行く方法です。しかし、ステータスを維持し、ファイルに保存する必要がありますか? – TriCore
また、効果的なJava項目「Strive for Failure Atomicity」も読んでください。これは、一貫性のない状態になる可能性のある失敗を最小限に抑えるために、コードを整理することについていくつかのアドバイスがあります。 –