OOP Implementation |
AOP Implementation |
|
ObserverProtocol.java
import java.util.WeakHashMap;
import java.util.List;
import java.util.LinkedList;
public abstract aspect ObserverProtocol {
protected interface Subject {}
protected interface Observer {}
private WeakHashMap<Subject, List<Observer>> perSubjectObservers;
protected List<Observer> getObservers(Subject subject) {
if (perSubjectObservers == null) {
perSubjectObservers = new WeakHashMap<Subject, List<Observer>>();
}
List<Observer> observers = perSubjectObservers.get(subject);
if (observers == null) {
observers = new LinkedList<Observer>();
perSubjectObservers.put(subject, observers);
}
return observers;
}
public void addObserver(Subject subject, Observer observer) {
getObservers(subject).add(observer);
}
public void removeObserver(Subject subject, Observer observer) {
getObservers(subject).remove(observer);
}
protected abstract pointcut subjectChange(Subject s);
after(Subject subject): subjectChange(subject) {
for (Observer o : getObservers(subject)) {
updateObserver(subject, o);
}
}
protected abstract void updateObserver(Subject subject, Observer observer);
}
|
Point.java
import java.awt.Color;
import java.util.HashSet;
public class Point implements ChangeSubject {
private HashSet<ChangeObserver> observers;
private int x;
private int y;
private Color color;
public Point(int x, int y, Color color) {
this.x = x;
this.y = y;
this.color = color;
this.observers = new HashSet<ChangeObserver>();
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setX(int x) {
this.x = x;
notifyObservers();
}
public void setY(int y) {
this.y = y;
notifyObservers();
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
notifyObservers();
}
public void addObserver(ChangeObserver o) {
this.observers.add(o);
}
public void removeObserver(ChangeObserver o) {
this.observers.remove(o);
}
public void notifyObservers() {
for (ChangeObserver o : observers) {
o.refresh(this);
}
}
}
|
Point.java
import java.awt.Color;
public class Point {
private int x;
private int y;
private Color color;
public Point(int x, int y, Color color) {
this.x = x;
this.y = y;
this.color = color;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
}
|
Screen.java
import java.util.HashSet;
public class Screen implements ChangeSubject, ChangeObserver {
private HashSet<ChangeObserver> observers;
private String name;
public Screen(String s) {
this.name = s;
observers = new HashSet<ChangeObserver>();
}
public void display(String s) {
System.out.println(name + ": " + s);
notifyObservers();
}
public void addObserver(ChangeObserver o) {
this.observers.add(o);
}
public void removeObserver(ChangeObserver o) {
this.observers.remove(o);
}
public void notifyObservers() {
for (ChangeObserver o : observers) {
o.refresh(this);
}
}
public void refresh(ChangeSubject s) {
String subjectTypeName = s.getClass().getName();
subjectTypeName = subjectTypeName.substring(subjectTypeName
.lastIndexOf(".") + 1, subjectTypeName.length());
display("update received from a " + subjectTypeName + " object");
}
}
|
Screen.java
public class Screen {
private String name;
public Screen(String s) {
this.name = s;
}
public void display(String s) {
System.out.println(name + ": " + s);
}
}
|
ChangeSubject.java
public interface ChangeSubject {
public void addObserver(ChangeObserver o);
public void removeObserver(ChangeObserver o);
public void notifyObservers();
}
|
CoordinateObserver.java
public aspect CoordinateObserver extends ObserverProtocol {
declare parents: Point implements Subject;
declare parents: Screen implements Observer;
protected pointcut subjectChange(Subject subject):
(call(void Point.setX(int)) ||
call(void Point.setY(int)) ) && target(subject);
protected void updateObserver(Subject subject, Observer observer) {
((Screen) observer)
.display("Screen updated (point subject changed coordinates).");
}
}
|
ChangeObserver.java
public interface ChangeObserver {
public void refresh(ChangeSubject s);
}
|
ColorObserver
import java.awt.Color;
public aspect ColorObserver extends ObserverProtocol {
declare parents: Point implements Subject;
declare parents: Screen implements Observer;
protected pointcut subjectChange(Subject subject):
call(void Point.setColor(Color)) && target(subject);
protected void updateObserver(Subject subject, Observer observer) {
((Screen) observer)
.display("Screen updated (point subject changed color).");
}
}
|
|
ScreenObserver.java
public aspect ScreenObserver extends ObserverProtocol {
declare parents: Screen implements Subject;
declare parents: Screen implements Observer;
protected pointcut subjectChange(Subject subject):
call(void Screen.display(String)) && target(subject);
protected void updateObserver(Subject subject, Observer observer) {
((Screen) observer)
.display("Screen updated (screen subject displayed message).");
}
}
|
Main.java
import java.awt.Color;
public class Main {
public static void main(String argv[]) {
// Creating Screen s1,s2,s3,s4,s5 and Point p
Screen s1 = new Screen("s1");
Screen s2 = new Screen("s2");
Screen s3 = new Screen("s3");
Screen s4 = new Screen("s4");
Screen s5 = new Screen("s5");
Point p = new Point(5, 5, Color.blue);
// s1 and s2 observe color changes to p
p.addObserver(s1);
p.addObserver(s2);
// s3 and s4 observe coordinate changes to p
p.addObserver(s3);
p.addObserver(s4);
// s5 observes s2's and s4's display() method
s2.addObserver(s5);
s4.addObserver(s5);
System.out.println("Changing p's color:");
p.setColor(Color.red);
System.out.println("Changing p's x-coordinate:");
p.setX(4);
}
}
|
Main.java
import java.awt.Color;
public class Main {
public static void main(String argv[]) {
// Creating Screen s1,s2,s3,s4,s5 and Point p
Screen s1 = new Screen("s1");
Screen s2 = new Screen("s2");
Screen s3 = new Screen("s3");
Screen s4 = new Screen("s4");
Screen s5 = new Screen("s5");
Point p = new Point(5, 5, Color.blue);
// s1 and s2 observe color changes to p
ColorObserver.aspectOf().addObserver(p, s1);
ColorObserver.aspectOf().addObserver(p, s2);
// s3 and s4 observe coordinate changes to p
CoordinateObserver.aspectOf().addObserver(p, s3);
CoordinateObserver.aspectOf().addObserver(p, s4);
// s5 observes s2's and s4's display() method
ScreenObserver.aspectOf().addObserver(s2, s5);
ScreenObserver.aspectOf().addObserver(s4, s5);
System.out.println("Changing p's color:");
p.setColor(Color.red);
System.out.println("Changing p's x-coordinate:");
p.setX(4);
}
}
|
Output
Changing p's color:
s1: update received from a Point object
s2: update received from a Point object
s5: update received from a Screen object
s3: update received from a Point object
s4: update received from a Point object
s5: update received from a Screen object
Changing p's x-coordinate:
s1: update received from a Point object
s2: update received from a Point object
s5: update received from a Screen object
s3: update received from a Point object
s4: update received from a Point object
s5: update received from a Screen object
|
Output
Changing p's color:
s1: Screen updated (point subject changed color).
s2: Screen updated (point subject changed color).
s5: Screen updated (screen subject displayed message).
Changing p's x-coordinate:
s3: Screen updated (point subject changed coordinates).
s4: Screen updated (point subject changed coordinates).
s5: Screen updated (screen subject displayed message).
|
Problem
- design pattern侵入原本的程式,將之複雜化
- 如果要將observer再加以功能區分,程式將會更複雜
|
Improvement
|