The Observer pattern is a very common design pattern that can be found in many systems, especially when it comes to the need for notification of changes in the state of the data.
This article takes Abstractcursor as an example, unfolds the analysis.
Observer mode, Observer pattern, is a very practical mode, I have been exposed to various platforms and have been involved in the project in the print template interpreter used in this mode.
1. Intentions
Defines a one-to-many dependency between objects, and when an object's state changes, all objects that depend on it are notified and automatically updated.
Hot words: dependency on Publish-subscribe event Notification Update Listener
2. Structure
This is the simplest observer pattern, where the target object is able to add and remove observers, and when a certain state or behavior changes, the notify notifies the registered observer to update the operation.
Analyzing the specific situation of the abstractcursor, we find that the actual work sometimes requires a unified management of the observer, even the observer type has many kinds and can be divided into several series, this time is to be more complex, through the rational stratification of the problem is good solution. Here's how we draw the observer pattern structure used in ABSTRACTCUROSR in Android, depending on the situation:
The viewer is divided into two series.
3. Code
The relevant core code is listed below:
- Public Abstract class Abstractcursor {
- //Definition Manager
- Datasetobservable mdatasetobservable = new datasetobservable ();
- Contentobservable mcontentobservable = new contentobservable ();
- //Register and uninstall two types of observers
- public void Registercontentobserver (Contentobserver observer) {
- MCONTENTOBSERVABLE.REGISTEROBSERVER (Observer);
- }
- public void Unregistercontentobserver (Contentobserver observer) {
- //cursor would unregister all observers when it close
- if (!mclosed) {
- MCONTENTOBSERVABLE.UNREGISTEROBSERVER (Observer);
- }
- }
- public void Registerdatasetobserver (Datasetobserver observer) {
- MDATASETOBSERVABLE.REGISTEROBSERVER (Observer);
- }
- public void Unregisterdatasetobserver (Datasetobserver observer) {
- MDATASETOBSERVABLE.UNREGISTEROBSERVER (Observer);
- }
- //2 Class Notification method
- protected void OnChange (boolean selfchange) {
- synchronized (mselfobserverlock) {
- Mcontentobservable.dispatchchange (Selfchange);
- if (Mnotifyuri! = null && selfchange) {
- Mcontentresolver.notifychange (Mnotifyuri, mselfobserver);
- }
- }
- }
- protected void Notifydatasetchange () {
- Mdatasetobservable.notifychanged ();
- }
- }
Then look at the Observable<t> class and the Datasetobservable class:
- Public Abstract class Observable<t> {
- /**
- * Viewer List
- */
- protected Final arraylist<t> mobservers = new arraylist<t> ();
- public void Registerobserver (T observer) {
- if (Observer = = null) {
- throw New IllegalArgumentException ("The Observer is null.");
- }
- synchronized (mobservers) {
- if (Mobservers.contains (Observer)) {
- throw New IllegalStateException ("Observer" + Observer + "is already registered.");
- }
- MOBSERVERS.ADD (Observer);
- }
- }
- public void Unregisterobserver (T observer) {
- if (Observer = = null) {
- throw New IllegalArgumentException ("The Observer is null.");
- }
- synchronized (mobservers) {
- int index = MOBSERVERS.INDEXOF (Observer);
- if (index = =-1) {
- throw New IllegalStateException ("Observer" + Observer + "is not registered.");
- }
- Mobservers.remove (index);
- }
- }
- public void UnregisterAll () {
- synchronized (mobservers) {
- Mobservers.clear ();
- }
- }
- }
And
- Public class Datasetobservable extends observable<datasetobserver> {
- /**
- * Notify all observers when data changes
- */
- public void notifychanged () {
- synchronized (mobservers) {
- For (Datasetobserver observer:mobservers) {
- Observer.onchanged ();
- }
- }
- }
- //... ... (Other methods)
- }
The Observer Datasetobserver class is an abstract class:
- Public Abstract class Datasetobserver {
- public void onChanged () {
- // do nothing
- }
- }
So we look at its subclasses specifically:
- Public class Alphabetindexer extends datasetobserver{
- /*
- * @hide is hidden by the Android system
- */
- @Override
- public void onChanged () {
- //Observed data changes, observers do what they should do
- super.onchanged ();
- Malphamap.clear ();
- }
- }
Contentobserver is similar.
4. Effects
(1). Behavioral mode
(2). Abstract coupling between the target and the Observer (Classic implementation).
(3). Support Broadcast communication (believe that Android developers should be enlightened after seeing it).
(4). Pay attention to unexpected updates, which is one of the reasons why the Watcher update is being managed.
Design mode-Viewer mode