倭マン's BLOG

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

事前処理・事後処理の織り込み 其ノ弐

前回はジョインポイント SIMULATE に事前処理・事後処理を織り込みました。 今回は、同様にしてジョインポイント ITERATE, EVOLVE に事前処理・事後処理を織り込みましょう。

ポイントカットの定義


以前にデータ出力処理を織り込んだ際、ITERATE, 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);
}

事前処理・事後処理の織り込みもこのポイントカットに対して行うので、このアスペクトを拡張して新たなアスペクトを作成します。

アドバイスの定義


処理の内容は、前回の SIMULATE ジョインポイントに対して行ったものとほとんど同じです:

public aspect IterationComponent extends IterationPointcut{

    void around(Iteration ite, PhysicalSystem ps)
            throws SimulationException:
            iterate(ite, ps){
        try{
            ite.prepareForIteration();
            proceed(ite, ps);
        }finally{
            ite.disposeForIteration();
        }
    }
    
    void around(Iteration ite, PhysicalSystem ps)
            throws SimulationException:
            evolve(ite, ps){
        try{
            ite.prepareForEvolution();
            proceed(ite, ps);
        }finally{
            ite.disposeForEvolution();
        }
    }

Iteration の事前処理・事後処理の上書き


Iteration オブジェクトがネスト構造を採っている場合、SIMULATE ジョインポイントの場合と違い、ジョインポイント ITERATE, EVOLVE に事前処理・事後処理を織り込む際には子要素の事前処理・事後処理を行ってはいけません()。 したがって、CompositeIteration の prepareForIteration(), disposeForIteration() を以下のように上書きします:

public aspect IterationComponent extends IterationPointcut{

    // 事前処理・事後処理に関するアドバイスの定義
    
    public void Iteration.prepareForIteration()
            throws SimulationException{

        // @Prepare(JoinPoint.ITERATE)
        // が付加されているを実行する。

        this.getDataOutputterContainer().prepareForIteration();
        this.getIterationCondition().prepareForIteration();
    }
    
    public void Iteration.disposeForIteration()
            throws SimulationException{
        
        this.getIterationCondition().disposeForIteration();
        this.getDataOutputterContainer().disposeForIteration();

        // @Dispose(JoinPoint.ITERATE)
        // が付加されているを実行する。
    }
}

prepareForEvolution(), disposeForEvolution() についても同様です。

優先順位の指定


IterationPointcut で定義されているポイントカットに複数のアドバイス (OutputState, IterationComponent) を織り込んでいるので、優先順位を指定しておかないと意図しない動作をする可能性があります。 優先順位の指定には「declare precedence」宣言を用います。 宣言するアスペクトは(何処でもいいんですが)IterationPointcut にしておくのが良いでしょう:

public abstract aspect IterationPointcut{
    
    declare precedence: IterationComponent, OutputState;

    // ポイントカット等の定義
}

超弦理論とM理論

超弦理論とM理論