倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

データ出力処理の織り込み

前回作成した DataOutputterContainer クラスを用いて「データ出力処理の織り込み」を行いましょう。

処理の織り込み場所は

  • 「始状態」「終状態」→ Iteration#iterate() メソッドの実行前後
  • 「更新後の状態」→ Iteration#evolve() メソッドの呼び出し後

となります。

ポイントカットの宣言


処理を織り込む前に、まずポイントカットを定義しておきましょう。 このポイントカットはまた別の処理を織り込むために使うので、抽象アスペクトとして定義しておきます:

public abstract aspect IterationPointcut{

    public pointcut iterate(Iteration ite, PhysicalSystem ps):
        execution(* Iteration.iterate(PhysicalSystem))
        && this(ite) && args(ps);

    public pointcut evolve(Iteration ite, PhysicalSystem ps):
        call(* Iteration.evolve(PhysicalSystem))
        && this(ite) && args(ps);
}

織り込む処理内で、Iteration オブジェクトの参照や引数として渡される PhysicalSystem オブジェクトが必要になる(かもしれない)ので、それらをポイントカットの引数として定義しておきます。 「thisJoinPoint」キーワードを使えば引数の定義を各必要はなくなりますが、「2つ程度の引数」なのと「型変換をしなくていい」ってことで、このような実装にしています。

アドバイスの実装


上記の IterationPointcut を用いて、状態の出力処理を織り込みましょう。 これには around アドバイスを用います:

public aspect OutputState extends IterationPointcut{

    void around(Iteration ite, PhysicalSystem ps)
            throws SimulationException:
            iterate(ite, ps){
        
        ite.getDataOutputterContainer().output(OutputTiming.INITIAL);
        proceed(ite, ps);
        ite.getDataOutputterContainer().output(OutputTiming.FINAL);
    }
    
    void around(Iteration ite, PhysicalSystem ps)
            throws SimulationException:
            evolve(ite, ps){
        
        proceed(ite);
        ite.getDataOutputterContainer().output(OutputTiming.AFTER_EVOLUTION);
    }
}

Iteration オブジェクトから前回定義した DataOutputterContainer を取得して、呼び出し場所にあったタイミングを指定してある DataOutputter を用いて出力を行います。 具体的な処理は DataOutputterContainer や DataOutputter に実装します。

アスペクト指向入門 -Java ・ オブジェクト指向から AspectJプログラミングへ

アスペクト指向入門 -Java ・ オブジェクト指向から AspectJプログラミングへ