0

このページでは、既存のクラスにメソッドを追加する方法を示し、それらの追加メソッドを呼び出すアスペクト内でメソッドを宣言する方法を示します。

これはそのページのコードです:

aspect PointObserving {
    private Vector Point.observers = new Vector();

    public static void addObserver(Point p, Screen s) {
        p.observers.add(s);
    }
    public static void removeObserver(Point p, Screen s) {
        p.observers.remove(s);
    }

    pointcut changes(Point p): target(p) && call(void Point.set*(int));

    after(Point p): changes(p) {
        Iterator iter = p.observers.iterator();
        while ( iter.hasNext() ) {
            updateObserver(p, (Screen)iter.next());
        }
    }

    static void updateObserver(Point p, Screen s) {
        s.display(p);
    }
}

このパターンを同じ設定 (オブザーバー パターン) で再利用しようとしていますが、Java コードのどこからでもオブザーバーを追加できるようにしたいと考えています。したがって、そのページに示されている例では、パッケージ内の別のクラスから次のようなことをしたいと考えています。

Point p = new Point(120, 230);
Screen s = getScreen();
PointObserving.addObserver(p, s);

ただし、「アスペクト」の PointObserving は、私の Java クラスには表示されません (パブリックに宣言しましたが)。

4

1 に答える 1

0

これを行う方法を見つけました -- どうやら、aspectJ を使用すると、追加のフィールドだけでなくメソッドも定義できます。そのためには、以下のようにアスペクトを変更するだけです (私がどのように に置き換えたかに注意してstaticくださいPoint.)

aspect PointObserving {
    private Vector Point.observers = new Vector();

    public void Point.addObserver(Point p, Screen s) {
        observers.add(s); //Legal to access observers here
    }
    public void Point.removeObserver(Point p, Screen s) {
        observers.remove(s); //Legal to access observers here
    }

    //Rest remains same as before.
}

通常のJavaクラスのどこかで、これを行うことができます:

Point p = new Point(120, 230);
Screen s = getScreen();
p.addObserver(s);

また、オブザーバーを弱参照として宣言する価値があります。したがって、

private Collection<Screen> Point.observers = Collections.newSetFromMap(new WeakHashMap<Screen, Boolean>());
//Rest remains same
于 2013-04-07T15:42:59.613 に答える