Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] Different ways to implement additional behaviour

Hello all, AspectJ provides different ways of making an aspect define and implement additional state associated with existing objects. Usually when there are several ways to do do something one of these is to be preferred over the others. I was hoping to get feedback to confirm which is best. I can picture at least three different ways to implement extra aspect state:
(1) introducing extra fields in the classes concerned, through
inter-type declarations (2) using per-aspects (most often perthis, I guess)
(3) using a structure (collection) within the aspect to map the
additional data to the objects;
I guess the first two options are frequently used. Option (3)
is tedious and error prone and probably should be avoided, except
in some complex cases such as the observer pattern. Presently I'm
inclined to prefer (2) over (1), because I feel introducing fields
is "heavy", and in such case all instances would carry the burden
of the extra state throughout their life cycle.
The question is, does everybody agree? If so, using (1) when (2) is
an option should perhaps be considered bad AspectJ style.
Below there is an example of (1) and (2) that shows what I'm thinking
of. It concerns two Audience aspects that record the number of times
each singer object executes the sing() method. Choice of implementation impacts on client code (RunSinger*.java)
=================================================================
Soprano.java:
public class Soprano {
 public void sing() {
    System.out.println("Ah! Je ris de me voir si belle dans ce miroir!");
 }
}
=================================================================
Tenor.java:
public class Tenor {
 public void sing() {
    System.out.println("La donna 'e mobile qual piuma al vento..");
 }
}
=================================================================
Baritone.java:
public class Baritone {
 public void sing() {
    System.out.println("O Freunde, nicht diese Toene!");
 }
}
=================================================================
Audience1.java - aspect implementing (1):
public aspect Audience1 {
 private interface Singer { }
 declare parents: (Soprano || Tenor || Baritone)
implements Singer;
 private int Singer._songCounter;
 public int Singer.songCount() {
    return this._songCounter;
}
 pointcut singing(Singer singer):
    execution(public * Singer+.sing(..)) && this(singer);
 after(Singer singer) returning: singing(singer) {
    singer._songCounter++;
 }
}
=================================================================
Audience2.java - aspect implementing (2):
public aspect Audience2 perthis(singing(Singer)) {
 private interface Singer { }
 declare parents: (Soprano || Tenor || Baritone)
implements Singer;
 private int _songCounter;
 public int songCount() {
    return this._songCounter;
}
 pointcut singing(Singer singer):
    execution(public * Singer+.sing(..)) && this(singer);
 after(Singer singer) returning: singing(singer) {
    this._songCounter++;
 }
}
=================================================================
RunSingers1.java - program test for (1):
public class RunSingers1 {
 public static void main(String[] args) {
    Soprano soprano = new Soprano();
    Tenor tenor = new Tenor();
Baritone baritone = new Baritone();
    soprano.sing();
    tenor.sing();
    baritone.sing();
soprano.sing();
    System.out.println("\nResults:\n" +
       "\tsoprano: "   + soprano.songCount() +
       "\n\ttenor: "   + tenor.songCount() +
       "\n\tbaritone: "+ baritone.songCount()
    );
 }
}
=================================================================
RunSingers2.java - program test for (2):
public class RunSingers2 {
 public static void main(String[] args) {
    Soprano soprano = new Soprano();
    Tenor tenor = new Tenor();
Baritone baritone = new Baritone();
    soprano.sing();
    tenor.sing();
    baritone.sing();
soprano.sing();
    System.out.println("\nResults:\n" +
       "\tsoprano: "   + Audience2.aspectOf(soprano).songCount() +
       "\n\ttenor: "   + Audience2.aspectOf(tenor).songCount() +
       "\n\tbaritone: "+ Audience2.aspectOf(baritone).songCount()
    );
 }
}
================================================================= Thanks for any feedback,
Miguel J. T. Pessoa Monteiro
Ph.D. student Minho University,Portugal
eMail: mmonteiro@xxxxxxxxxxxx
URL:http://gec.di.uminho.pt/mpm/


Back to the top