View Javadoc

1   //----------------------------------------------------------------------
2   // 
3   // PerfectJPattern: "Design patterns are good but components are better!" 
4   // ISubject.java Copyright (c) 2009 Giovanni Azua Garcia
5   // bravegag@hotmail.com
6   //  
7   // This program is free software; you can redistribute it and/or
8   // modify it under the terms of the GNU General Public License
9   // as published by the Free Software Foundation; either version 3
10  // of the License, or (at your option) any later version.
11  //
12  // This program is distributed in the hope that it will be useful,
13  // but WITHOUT ANY WARRANTY; without even the implied warranty of
14  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  // GNU General Public License for more details.
16  //
17  // You should have received a copy of the GNU General Public License
18  // along with this program; if not, see <http://www.gnu.org/licenses/>.
19  //
20  //----------------------------------------------------------------------
21  package org.perfectjpattern.core.api.behavioral.observer;
22  
23  /**
24   * <b>Observer Design Pattern</b>: Define a one-to-many dependency between
25   * objects so that when one object changes state, all its dependents are
26   * notified and updated automatically. (Gamma et al, Design Patterns)<br/>
27   * <br/>
28   * 
29   * <b>Responsibility</b>: Abstract generic definition of the "Subject".
30   * pattern role:<br/>
31   * <ul>
32   * <li>Knows its observers. Any number of <code>IObserver</code> objects may
33   * observe a <code>ISubject</code>.</li>
34   * <li>Provides an interface for attaching and detaching <code>IObserver</code>
35   * objects.</li>
36   * </ul>
37   * 
38   * <b>Notes</b>:
39   * Improves over the original GoF recipe and Java Observer implementation 
40   * in that:<br/>
41   * <ul>
42   * <li>Push over Pull approach: <code>IObserver</code> instances are not 
43   * coupled to the <code>ISubject</code> interface i.e. there is no need for the 
44   * <code>IObserver</code> to query <code>ISubject</code>'s state. State 
45   * change or Message content is pushed to the {@link #notifyObservers} 
46   * callback method.</li> 
47   * <li>Strongly typed generic parameter eliminates the need for 
48   * <code>IObserver</code> to downcast the parameter as is the case for 
49   * e.g. <code>java.util.Observer</code> implementation.</li>
50   * </ul>
51   *
52   * <br/>
53   * Example usage:
54   * <pre><code>
55   *    //
56   *    // Create Observer Pattern elements 
57   *    //  
58   *    ISubject&lt;NullEventData&gt; mySubject = new ConcreteSubject();
59   *    IObserver&lt;NullEventData&gt; myFirstObserver = new ConcreteObserver();
60   *    IObserver&lt;NullEventData&gt; mySecondObserver = new ConcreteObserver();
61   *    
62   *    //
63   *    // Subscribe multiple Observer instances to the Subject
64   *    //
65   *    mySubject.attach(myFirstObserver, mySecondObserver);
66   *    
67   *    //
68   *    // Notify all subscribed Observers, optionally pass some Event 
69   *    // data associated with the Event.
70   *    //
71   *    mySubject.notifyObservers(NullEventData.getInstance());
72   *    
73   *    //
74   *    // Detach Observer instances
75   *    //
76   *    mySubject.detach(myFirstObserver);
77   * </code></pre>
78   *
79   * @param <E> Type of event data that this <code>ISubject</code> 
80   * notifies with.
81   * 
82   * @author <a href="mailto:bravegag@hotmail.com">Giovanni Azua</a>
83   * @version $Revision: 1.0 $ $Date: Jun 11, 2007 6:21:08 AM $
84   */
85  public 
86  interface ISubject<E> 
87  {
88      //-------------------------------------------------------------------------
89      // public
90      //-------------------------------------------------------------------------
91      /**
92       * Attaches a variable list of <code>IObserver</code> instances to the 
93       * <code>ISubject</code> instance.
94       * 
95       * @param anObservers <code>IObserver</code> instances to be attached. 
96       * @throws IllegalArgumentException 'anObservers' must not be null. 
97       */
98      public void 
99      attach(IObserver<E>... anObservers);
100 
101     //-------------------------------------------------------------------------
102     /**
103      * Detaches all registered <code>IObserver</code> instances from this
104      * <code>ISubject</code>
105      */
106     public void 
107     clear();
108 
109     //-------------------------------------------------------------------------
110     /**
111      * Detaches a variable list of <code>IObserver</code> instances from the 
112      * <code>ISubject</code> instance.
113      * 
114      * @param anObservers <code>IObserver</code> instances to be detached.
115      * @throws IllegalArgumentException 'anObservers' must not be null. 
116      */
117     public void 
118     detach(IObserver<E>... anObservers);
119 
120     //-------------------------------------------------------------------------
121     /**
122      * Notifies the attached <code>IObserver</code> instances that a change 
123      * has occurred. It is compulsory to provide a non null parameter 
124      * <code>anEventData</code>. For situations where passing information is 
125      * not required use instead <code>NullEventData</code> singleton instance.
126      * 
127      * @param anEventData Event data pushed to <code>IObserver</code> 
128      *        instances.
129      * @throws IllegalArgumentException 'anEventData' must not be null. 
130      */
131     public void 
132     notifyObservers(E anEventData);
133 
134     //-------------------------------------------------------------------------
135     /**
136      * Returns the number of attached <code>IObserver</code> instances
137      * 
138      * @return Number of attached <code>IObserver</code> instances.
139      */
140     public int 
141     size();
142 }