Implementing observer patterns with AOP

Source: Internet
Author: User
Tags abstract aop
Viewer (Observer) mode
Purpose: Defines a one-to-many dependency between objects, so that when an object's state changes, all its dependencies are notified and updated automatically.
It is the Queen of OO design patterns. This pattern is widely used (especially in GUI applications) and forms a critical part of the MVC architecture. It deals with complex problems and is relatively good at solving such problems. However, from the point of view of implementing the necessary effort and code understanding, it still brings some difficult problems to solve.
Insufficient: The Observer (Observer) mode requires that you first hack into existing classes in the system before you can support the pattern-at least in the Java language.
Aspects can reduce the burden of intrusive patterns like the Observer (Observer) pattern, making the pattern participants more flexible because they do not need to contain pattern code. Moreover, the pattern itself can become the basic aspect of abstraction, allowing developers to reuse it by importing and applying it, without having to rethink the pattern every time.
Here's an example to illustrate:
Consider the following scenario:
The Accountmanager object is able to observe account so that they can send an e-mail message to the salesperson when the state of the accounts changes.
The code is as follows:

public class Account {

private int state;
private String name;

Public String GetName () {
return name;
}
Public account (String name) {
Super ();
THIS.name = name;
}
public int getState () {
return state;
}

public void SetState (int.) {
This.state = State;
}
@Override
Public String toString () {
return name;
}
}

public class Accountmanager {

public void SendEmail (account account) {
System.out.println ("Send Email:" + account);
}
}

Take a look at how the Java code implements the Observer pattern

Viewer of the Java language
Although the differences in implementation are obvious, there are some similarities between them. Regardless of how the observer is implemented, the following 4 questions must be answered in the code:
1. Which object is the principal and which object is the observer.
2. When the subject should send a notification to its observer.
3. What the Observer should do when receiving a notification.
4. Observe when the relationship should begin and when it will be terminated.

Role Definitions
Start by assigning the role from the marker interface first. The Observer interface defines only one method: Update (), which corresponds to the action that is performed when Subject sends a notification. Subject is taking on more responsibilities. Its marker interface defines two methods, one to track the observer and the other to notify the event's observers.

Public interface Observer {

public void Update (Subject Subject);
}

Public interface Subject {
public void Addobserver (Observer o);
public void Removeobserver (Observer o);
public void notifyobservers ();
}
Once these roles are defined, they can be applied to the corresponding roles in the system.

Apply Observer Role

public class Accountmanager implements Observer {

public void Update (Subject Subject) {
SendEmail (account) subject);
}
}

tracking and notifying observers
Once the work is done, it can be transferred to subject. In this case, you need to modify the account:
Private Set observers = new HashSet ();
public void Addobserver (Observer o) {
Observers.add (o);
}
public void Removeobserver (Observer o) {
Observers.remove (o);
}
public void Notifyobservers () {
for (Observer o:observers) {
O.update (this);
}
}
Triggering Events
The classes have now been tuned to their roles in the pattern. However, you also need to go back and trigger a notification when the corresponding event occurs.
Account
public void SetState (int.) {
if (this.state! = State) {
This.state = State;
Notifyobservers ();
}
}
start an observation relationship

public class Observerclient {

public static void Main (string[] args) {
Accountmanager manager = new Accountmanager ();
Accountmanager manager2 = new Accountmanager ();
Account Account = new Account ("Account1");
Account.addobserver (manager);
Account.addobserver (Manager2);
Account.setstate (1);
}
}

AspectJ Observer

defining abstract classes to implement observers

Use JAVA5 generics to define observations and bodies
Public abstract class Abstractsubjectobserver<sub, obv> {

Empty item not allowed
protected static void Iaxifnull (Object item, String name) {
if (null = = Item) {
throw new IllegalArgumentException ("null" + name);
}
}
Used to hold all object relationships between the principal and the Observer
Private final hashmap<sub, arraylist<obv>> fobservers = new hashmap<sub, arraylist<obv>> ();

Protected Abstractsubjectobserver () {

}

Public synchronized void Addobserver (SUB subject, OBV observer) {
Iaxifnull (Subject, "subject");
IAXIFNULL (Observer, "Observer");
Getobservers (subject). Add (Observer);
}

Public synchronized void Removeobserver (
Sub subject,
OBV observer) {
Iaxifnull (Subject, "subject");
IAXIFNULL (Observer, "Observer");
Getobservers (subject). Remove (Observer);
}

Public synchronized arraylist<obv> getobservers (Sub subject) {
Iaxifnull (Subject, "subject");
arraylist<observer> result = Fobservers.get (subject);
if (null = = result) {
result = new arraylist<observer> ();
Fobservers.put (subject, result);
}
return result;
}
Change the subject state to update all observer objects
protected void subjectchanged (Sub subject) {
Iaxifnull (Subject, "subject");
arraylist<observer> list = getobservers (subject);
if (!list.isempty ()) {
Updateobservers (Subject, collections.unmodifiablelist (list));
}
}

Update all observer actions to invoke the specific updateobserver
protected synchronized void Updateobservers (
Subject Subject,
List<observer> observers) {
Iaxifnull (Subject, "subject");
Iaxifnull (observers, "observers");
for (Observer observer:observers) {
Updateobserver (subject, observer);
}
}
Subclass implementation required, specific update operation
protected abstract void Updateobserver (Subject Subject, Observer Observer);

}

Definition aspects:
Public abstract aspect subjectobserver<sub, obv> extends
Abstractsubjectobserver<sub, obv> {

Code that needs to be crosscutting, indicating what needs to be triggered by the observer pattern
protected abstract pointcut changing ();

After the state changes, all observers are triggered
After (Sub subject) Returning:target (subject) && changing () {
Subjectchanged (subject);
}
}

No need to change the original implementation, see how the client initiates the observation relationship
public class Observerclient {

public static void Main (string[] args) {
Account account=new Account ("Account1");
Client Client=client.aspectof ();
Client.addobserver (Account,new Accountmanager ());
Client.addobserver (Account,new Accountmanager ());
Account.setstate (1);
}
Static aspect Client extends Subjectobserver<account, accountmanager> {

protected pointcut changing (): Execution (void account.setstate (int));

protected void Updateobserver (account account, Accountmanager Manager) {
Manager.sendemail (account);
}
}
}

analysis of the AspectJ observer
Easy to understand: From the participant's perspective, the AOP version of the Observer is simpler
Reuse: It's easy to implement reuse

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.