Definition: Using the claims mentioned in the head first design pattern
The Observer pattern defines a one-to-many dependency that allows one or more observer objects to listen to a Subject object. In this way, when the state of the observer changes, it is necessary to notify the appropriate observers so that the observer objects can be updated automatically.
Brief introduction:
The Observer pattern (Observer) perfectly separated the observer from the observed object. For example, the user interface can be used as an observer, the business data is the Observer, the user interface observes the changes in the business data, and when the data changes, it is displayed on the interface.
One of the principles of object-oriented design is:
Each class in the system focuses on one function, not on the other. An object only does one thing and does it well. The Observer pattern defines a clear boundary between the modules, improving the maintainability and reusability of the application.
The observer design pattern defines a one-to-many dependency between objects, so that when the state of an object changes, all objects that depend on it are notified and refreshed automatically. Implementation method
When implementing the observer pattern, it is important to note that the interaction between the observer and the observed object does not reflect a direct call between the classes, otherwise it will tightly couple the observer and the observed object, fundamentally violating the principle of object-oriented design. Neither the Observer "observes" the object of observation, nor the observer notifies the observer of its own change, should not be called directly.
Constituent elements: Subject matter is the object observed by the observer, and a subject must have the following three characteristics.
A reference to the observer who holds the listener
Support for adding and removing observers
Subject status change, notify Observer
Observers
When the subject changes, it is the characteristic that the observer must possess to receive the notification for the specific treatment.
1. Examples of custom implementations:
Code: (Generics and reflection are used)
//Observers, classes that need to use the observer pattern need to implement this interface Public interface Observer{ voidUpdate (OBJECT...OBJS);}//Observer (an abstract class for easy extension) Public Abstract class Observable{ Public FinalArraylist<class<?>> obserlist =NewArraylist<class<?>> ();/**attachobserver (registered observer by instance) *<b>notice:</b>obcan ' Tbenull,oritwillthrownullpointerexception **/ Public<T>void Registerobserver(T ob) {if(ob==NULL)Throw NewNullPointerException (); This. Registerobserver (Ob.getclass ()); }/** *attachobserver (registered observer through Class) * @paramcls */ Public void Registerobserver(class<?> CLS) {if(cls==NULL)Throw NewNullPointerException ();synchronized(obserlist) {if(!obserlist.contains (CLS)) {Obserlist.add (CLS); } } }/**unattachobserver (logoff observer) *<b>notice:</b> *<b>itreverseswithattachobserver () method</b > **/ Public<T>void Unregisterobserver(TOB) {if(ob==NULL)Throw NewNullPointerException (); This. Unregisterobserver (Ob.getclass ()); }/**unattachobserver (logoff observer, sometimes not available to instance) *<b>notice:</b> *<b>itreverseswithattachobserver () Method</b> **/ Public void Unregisterobserver(CLASS<?>CLS) {if(cls==NULL)Throw NewNullPointerException ();synchronized(obserlist) {Iterator<class<?>>iterator=obserlist.iterator (); while(Iterator.hasnext ()) {if(Iterator.next (). GetName (). Equals (Cls.getname ())) {Iterator.remove (); Break; } } } }/**detachallobservers*/ Public void UnregisterAll(){synchronized(obserlist) {obserlist.clear (); } }/**ruturnthesizeofobservers*/ Public int countobservers(){synchronized(obserlist) {returnobserlist.size (); } }/** *NOTIFY All observer (notifies all observers, implemented in subclasses) * @paramobjs */ Public Abstract void notifyobservers(Object ... objs);/** *notify One certain observer (notifies a certain observer) * @paramcls * @paramobjs * * Public Abstract void Notifyobserver(class<?> cls, Object ... objs);/** *notifyonecertainobserver * @paramcls * @paramobjs * * Public Abstract<T>void Notifyobserver(t T, Object ... objs);}//target observed by Public class concreteobservable extends Observable{ Private StaticConcreteobservableinstance =NULL;Private concreteobservable(){}; Public Static synchronized concreteobservablegetinstance(){if(Instance = =NULL) {instance=newconcreteobservable (); } returninstance; }@Override Public<T>void Notifyobserver(t T, Object ... objs) {if(T = =NULL)Throw NewNullPointerException (); This. Notifyobserver (T.getclass (), OBJS); }@Override Public void notifyobservers(Object ... objs) { for(class<?>cls:obserlist) { This. Notifyobserver (CLS, OBJS); } }//Through the Java Reflection mechanism to implement the call @Override Public void Notifyobserver(Class<?>cls, OBJECT...OBJS) {if(CLS = =NULL)Throw NewNullPointerException (); Method[] methods = Cls.getdeclaredmethods (); for(Method method:methods) {if(Method.getname (). Equals ("Update")){Try{Method.invoke (CLS,OBJS); Break; }Catch(IllegalArgumentException e) {E.printstacktrace (); }Catch(Illegalaccessexception e) {E.printstacktrace (); }Catch(InvocationTargetException e) {E.printstacktrace (); } } } }}//Use (implement Observer interface) Public class Text extends Activity implements Observer{ Publicvoidoncreate (...) {concreteobservable.getinstance (). Registerobserver (Text.class); .... }//Implement Interface processingPublicvoidupdate (OBJECT...OBJS) {//Do operations such as updating data, updating UI, etc.}}
2.java built-in implementation method:
Java.util.Observable This is a class, not an interface, and the theme needs to inherit this class.
Java.util.Observer This is an interface where listeners need to implement this interface.
Code:
Import Java.util.observable;import java.util.Observer; Public class mainroot { Public Static voidMain (string[] args) {Observer consumer =NewConsumer (); Milkprovider Provider =NewMilkprovider (); Provider.addobserver (consumer); Provider.milkproduced (); }Static class milkprovider extends Observable { Public voidMilkproduced () {setchanged ();//State change, must be calledNotifyobservers (); } }Static class Consumer implements Observer {@Override Public voidUpdate (Observable arg0, Object arg1) {System.out.println ("Consumer update ..."+ arg0 +"; arg1="+ arg1); } }}
Setchange explanation
Source:
protectedsynchronizedvoidsetChanged() { true;}
The meaning of Setchange:
1. Filter valid notifications, only valid notifications can call setchanged. For example, my friends circle a state, friend a likes, follow the status of the point like and comment is not each to notify A, only a friend triggered action will notify a.
2. Easy to revoke notification operations, in the subject, we can set a lot of setchanged, but in the end for some reason need to cancel notification, we can use clearchanged easy to solve the problem.
3. Initiative control, because setchanged is protected, and the Notifyobservers method is public, which leads to the possibility of an external random call notifyobservers, but the external cannot call setchanged, So the real control should be on the subject here.
How to proactively get notifications: a topic is required to provide getter methods for some data, and observers simply call getter to take data processing. Code:
Static class milkprovider extends Observable { Public voidMilkproduced () {setchanged ();//State change, must be calledNotifyobservers (); } PublicFloat GetPrice () {return 2.5F } }Static class Consumer implements Observer {@Override Public voidUpdate (Observable arg0, Object arg1) {Milkprovider Provider = (Milkprovider) arg0; System.out.println ("Milk price ="+ Provider.getprice ()); } }
The advantages of the Observer pattern:
1. The observer adds or removes code that does not need to modify the subject, just invoke the Add or delete method of the topic.
2. The subject is only responsible for notifying the observer, but does not need to know how the observer handles the notification.
3. Observers only need to wait for topic notifications, without observing the details of the topic.
4. Due to passive acceptance, the subject change notice will not be missed under normal circumstances. and active acquisition, due to the timing of the problem, may lead to miss some states.
Disadvantages:
1. The subject holds the observer's reference, and if it is not handled properly, removing the observer from the subject can cause the observer to not be recycled.
2. If the observer implements a code-specific problem, it causes the topic and the Observer object to form a circular reference, and some garbage collector with reference counting may cause it to fail to recycle.
My QR code is as follows, welcome to exchange discussion
You are welcome to pay attention to the "It question summary" subscription number. Every day to push the classic face test and interview tips, are dry! The QR code of the subscription number is as follows:
Reference:
Http://baike.baidu.com/view/1854779.htm
Http://droidyue.com/blog/2015/06/27/desgign-pattern-observer/index.html
Java Design Pattern-viewer mode