メソッドがあり、このメソッド内にブロックがあります。
public void method()
{
[block instructions]
}
しかし、このメソッドは私のプログラムで 2 回呼び出されます。このブロックを 1 回だけ実行し、メソッドが最初に出現したときだけ実行したいと思います。それを行うための最良かつエレガントな方法は何でしょうか?
メソッドがあり、このメソッド内にブロックがあります。
public void method()
{
[block instructions]
}
しかし、このメソッドは私のプログラムで 2 回呼び出されます。このブロックを 1 回だけ実行し、メソッドが最初に出現したときだけ実行したいと思います。それを行うための最良かつエレガントな方法は何でしょうか?
private static final AtomicBoolean hasRunAtom = new AtomicBoolean();
public void method() {
if (hasRunAtom.getAndSet(true)) return;
[block instructions]
}
大幅に過剰に設計されるリスクがありますが、実際には状態パターンを提案します。基本的に、State
抽象化があります。
interface State extends Runnable {}
2つの実装で:
class FirstState extends State {
public void run() {
//[block of code]
state = new SecondState();
}
}
class SecondState extends State {
public void run() {
//[block instructions]
}
}
FirstState
スイッチstate
電流:
private State state = new FirstState();
method()
現在、条件付きロジックはありません。
public void method()
{
state.run();
}
ただし、99%の場合、boolean
フラグで十分です...
更新:上記の解決策はスレッドセーフではありません。必要な場合は、シンプルAtomicReference<State> state
しません十分であるか(以下のMarko Topolnikコメントを参照)、または全体を同期する必要がありますmethod()
:
public synchronized void method()
{
state.run();
}
まず、簡単で迅速な方法が必要な場合は、単純なブールフラグを使用します(同時実行の問題を忘れずに、@ Marko Topolnikソリューションを使用してください)。
しかし、@ Tomasz Nurkiewiczが言及するような状態パターンを使用するのではなく、すでに理論的な議論を開いてデザインパターンについて話し合った場合は、シングルトン(よりアンチなデザインパターンだと言う人もいます)と1つだけを実現する方法を考えることをお勧めしますこのクラスのインスタンスであるため、このクラスのインスタンスを要求すると、コンストラクターは最初の呼び出しでのみ呼び出されます。
より多くの「箱の外」のソリューションが必要な場合は、aopを使用できます
おそらくメソッドを再設計する必要があります。メソッドが2回目に実行されたときに何か別のことをする場合、プログラムを理解しようとする人にとっては混乱を招きます。
プログラムの別の場所から2回目に呼び出されましたか?その場合、最も簡単な方法は、複製されたビットを別のメソッドに抽出することです。
method() {
// Do stuff that's run only the first time
method2()
}
method2() {
// Do stuff that's run both times
}
同じ場所から呼び出された場合は、コードが2回目に何か別のことが起こることを期待している理由を自問する必要があります。