耳にしたことがある「Execute Around」という慣用句(または類似の慣用句)とは何ですか? なぜそれを使用するのでしょうか、また、なぜ使用したくないのでしょうか?
ベストアンサー1
基本的に、これは、リソースの割り当てやクリーンアップなど、常に必要なことを実行するメソッドを記述し、呼び出し元に「リソースで何をしたいか」を渡すパターンです。例:
public interface InputStreamAction
{
void useStream(InputStream stream) throws IOException;
}
// Somewhere else
public void executeWithFile(String filename, InputStreamAction action)
throws IOException
{
InputStream stream = new FileInputStream(filename);
try {
action.useStream(stream);
} finally {
stream.close();
}
}
// Calling it
executeWithFile("filename.txt", new InputStreamAction()
{
public void useStream(InputStream stream) throws IOException
{
// Code to use the stream goes here
}
});
// Calling it with Java 8 Lambda Expression:
executeWithFile("filename.txt", s -> System.out.println(s.read()));
// Or with Java 8 Method reference:
executeWithFile("filename.txt", ClassName::methodName);
呼び出しコードでは、オープン/クリーンアップ側について心配する必要はありません。 によって処理されますexecuteWithFile
。
Java ではクロージャが非常に冗長であるため、これは正直言って苦痛でしたが、Java 8 以降ではラムダ式を他の多くの言語 (C# ラムダ式や Groovy など) と同様に実装できるようになり、この特殊なケースは Java 7 以降ではtry-with-resources
ストリームAutoClosable
を使用して処理されます。
「割り当てとクリーンアップ」は典型的な例ですが、トランザクション処理、ログ記録、より多くの権限でコードを実行するなど、他にも多くの例があります。基本的には、テンプレートメソッドパターンただし、継承はありません。