Observer Design Pattern in Java ( SE and EE )

SE and EE versions:

SE version

package it.i88.ca.example.se.observer;
 
import java.util.Observable;
import java.util.Observer;
 
class MyObserver implements Observer {
 
    public void update(Observable o, Object arg) {
        System.out.println("update: " + arg);
    }
}


package it.i88.ca.example.se.observer;
 
public class ObserverTest {
 
    public static void main(String[] args) {
        Observered oed = new Observered();
        MyObserver mo1 = new MyObserver();
        MyObserver mo2 = new MyObserver();
      
        oed.addObserver(mo1);
        oed.addObserver(mo2);
      
        oed.updateNoticeBoard("Event from i88.ca occurs");
 
    }
}


package it.i88.ca.example.se.observer;
 
import java.util.Observable;
 
class Observered extends Observable {
 
    private String event;
 
    public String getEvent() {
        return event;
    }
 
    public void updateNoticeBoard(String notice) {
        this.event = notice;
        setChanged();
        notifyObservers(notice);
    }
}

Source in GitHub

Problems with java.util.Observable
Because Observable is a class, you have to subclass it. That means you can’t add on the Observable behavior to an existing class that already extends another superclass.
This limits its reuse potential.
Also because there isn't an Observable interface, you can’t even create your own implementation that plays well with Java’s built-in Observer API. Nor do you have the option of swapping out the java.util implementation for another implementation.

In the Observable API, the setChanged() method is protected. This means you can’t call setChanged() unless you've subclassed Observable. This means you can’t even create an instance of the Observable class and compose it with your own objects, you have to subclass. The design violates the design principle of favoring composition over inheritance.

//*********************
EE version
///////////////////////////////////////////

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>it.i88.ca</title>
    </h:head>
    <h:body>
        <h:form>
            <h:commandButton value="Fire!" action="#{observerTest.fire()}"/>
        </h:form>
    </h:body>
</html>


package ca.i88.sample.pattern.observer.ee;
 
import java.util.Date;
import javax.enterprise.event.Event;
import javax.inject.Inject;
import javax.inject.Named;
 
/**
 *
 * @author it.i88.ca
 */
@Named
public class ObserverTest {
 
    @Inject
    Event<I88caEvent> event;
 
    public void fire() {
        event.fire(new I88caEvent("event fired at: " + new Date()));
    }
 
}


package ca.i88.sample.pattern.observer.ee;
 
/**
 *
 * @author it.i88.ca
 */
class I88caEvent {
 
    private String msg;
 
    public String getMsg() {
        return msg;
    }
 
    public I88caEvent(String msg) {
        this.msg = msg;
    }
 
}



package ca.i88.sample.pattern.observer.ee;
 
import javax.ejb.Stateless;
import javax.enterprise.event.Observes;
 
/**
 *
 * @author it.i88.ca
 */
@Stateless
public class I88caEventListener {
 
    public void listen(@Observes I88caEvent event) {
        System.out.println(event.getMsg());
    }
 
}

Source code in GitHub

Featured Post

Updated Coupons / promo codes for Google Apps for Work / Business

To redeem: 1. Sign up for Google Apps   2. Go to your billing settings  3. Choose your payment plan  4. Enter your promo code ...