import java.util.ArrayList; import java.util.List; class PlayList { private static PlayList instance; private List list; private PlayList() { list = new ArrayList(); } public static PlayList instance() { if(instance==null ) { instance = new PlayList(); } return instance; } public void enqueue(Song song) { list.add(song); if(Player.instance().isIdle()) { new Thread() { public void run() { System.out.println("Playing playlist..."); for (Song s : list) { Player.instance().play(s.getName()); } } }.start(); } } } class Song { private String name; public Song(String name) { this.name = name; } public String getName() { return name; } } class Player { private static Player instance; private Player() {} public static Player instance() { if(instance==null ) { instance = new Player(); } return instance; } public void play(String name) { System.out.println("Playing Song "+name+"..."); } public boolean isIdle() { return true; } } class Jukebox { public void play(Song song) { Player.instance().play(song.getName()); } } class Main { public static void main(String[] args) { Song song = new Song("Merry XMas"); Jukebox jukebox = new Jukebox(); jukebox.play(song); } } aspect PlaylistAspect { void around(Song song) : call(public void Jukebox.play(Song)) && args(song) { PlayList.instance().enqueue(song); } } aspect CreditsAspect { void around() : call(public void Jukebox.play(Song)) { if(Credits.instance().enoughCredits()) { System.out.println("Withdrawing credit."); Credits.instance().withDraw(); proceed(); } else { throw new InsufficientCreditsException(); } } } class Credits { private static final int INITIAL_CREDITS = 10; private static Credits instance; private int credits; private Credits() { credits = INITIAL_CREDITS; } public static Credits instance() { if(instance==null ) { instance = new Credits(); } return instance; } public boolean enoughCredits() { return credits > 0; } public void withDraw() { credits--; } } @SuppressWarnings("serial") class InsufficientCreditsException extends RuntimeException { public InsufficientCreditsException() { super(); } public InsufficientCreditsException(String message, Throwable cause) { super(message, cause); } public InsufficientCreditsException(String message) { super(message); } /** * @param cause */ public InsufficientCreditsException(Throwable cause) { super(cause); } }