Learning JavaScript Design Patterns the Observer Pattern

Source: Internet
Author: User

The Observer Pattern

The Observer is a design pattern where an object (known as a subject) maintains a list of objects depending on it (observe RS), automatically notifying them of any changes to the state.

When a subject needs to notify observers on something interesting happening, it broadcasts a notification to the Observ ERS (which can include specific data related to the topic of the notification).

When we do longer wish for a particular observer to being notified of changes by the subject they is registered with, the SU Bject can remove them from the list of observers.

It's often useful to refer back to published definitions of design patterns that is language agnostic to get a broader SE NSE of their usage and advantages over time. The definition of the Observer pattern provided in the GoF book, Design patterns:elements of reusable object-oriented Software, is:

"One or more observers is interested in the state of a subject and registers their interest with the subject by attaching themselves. When something changes in we subject that the observer could be interested in, a notify message is sent which calls the UPD Ate method in each observer. When the observer was no longer interested in the subject's state, they can simply detach themselves. "

We can now expand on the "what we've learned to implement" the Observer pattern with the following components:

    • Subject:maintains A list of observers, facilitates adding or removing observers
    • Observer:provides a update interface for objects, need to being notified of a Subject ' s changes of state
    • Concretesubject:broadcasts notifications to observers in changes of state, stores the state of Concreteobservers
    • Concreteobserver:stores a reference to the ConcreteSubject, implements an update interface for the Observer to ensure STA Te is consistent with the Subject ' s

First, let's model the list of dependent observers a subject may have:

functionobserverlist () { This. observerlist = [];} ObserverList.prototype.add=function(obj) {return  This. Observerlist.push (obj);}; ObserverList.prototype.count=function(){  return  This. Observerlist.length;}; ObserverList.prototype.get=function(index) {if(Index >-1 && Index < This. Observerlist.length) {    return  This. observerlist[index]; }}; ObserverList.prototype.indexOf=function(obj, startIndex) {vari =StartIndex;  while(I < This. Observerlist.length) {    if( This. observerlist[i] = = =obj) {      returni; } I++; }   return-1;}; ObserverList.prototype.removeAt=function(index) { This. Observerlist.splice (Index, 1 );};

Next, let's model the Subject and the ability to add, remove or notify observers on the Observer list.

functionSubject () { This. Observers =Newobserverlist ();} Subject.prototype.addObserver=function(Observer) { This. OBSERVERS.ADD (Observer);}; Subject.prototype.removeObserver=function(Observer) { This. Observers.removeat ( This. OBSERVERS.INDEXOF (Observer, 0 ) );}; Subject.prototype.notify=function(context) {varObservercount = This. Observers.count ();  for(vari=0; i < Observercount; i++){     This. Observers.get (i). Update (context); }};

We then define a skeleton for creating new observers. The update functionality here is overwritten later with custom behaviour.

// The Observer function Observer () {  thisfunction() {    //  ...   };}

In our sample application using the above Observer components, we now define:

    • A button for adding new observable checkboxes to the page
    • A control checkbox which would act as a subject, notifying other checkboxes they should be checked
    • A container for the new checkboxes being added

We then define ConcreteSubject and concreteobserver handlers for both adding new observers to the page and implementing th e updating interface. See below for inline comments on what these the "the context of our example."

Html:

<button id= "Addnewobserver" >add New Observer checkbox</button><input id= "Maincheckbox" type= "checkbox "/><div id=" Observerscontainer "></div>

Sample script:

//Extend An object with an extensionfunctionextend (extension, obj) { for(varKeyinchextension) {Obj[key]=Extension[key]; }} //References to our DOM elements varControlcheckbox = document.getElementById ("Maincheckbox"), Addbtn= document.getElementById ("Addnewobserver"), Container= document.getElementById ("Observerscontainer" ); //Concrete Subject //Extend the controlling checkbox with the Subject classExtendNewSubject (), Controlcheckbox); //clicking the checkbox would trigger notifications to its observersControlcheckbox.onclick =function() {controlcheckbox.notify (controlcheckbox.checked);}; Addbtn.onclick=Addnewobserver;//Concrete Observer functionAddnewobserver () {//Create a new checkbox to be added  varCheck = document.createelement ("Input" ); Check.type= "checkbox"; //Extend the checkbox with the Observer classExtendNewObserver (), check); //Override with Custom update behaviourCheck.update =function(value) { This. checked =value;   }; //ADD The new observer to our list of observers  //For our main subjectcontrolcheckbox.addobserver (check); //Append the item to the containercontainer.appendchild (check);}

In this example, we looked on how to implement and utilize the Observer pattern, covering the concepts of a Subject, Obser ver, ConcreteSubject and Concreteobserver.

Differences between the Observer and Publish/subscribe Pattern

Whilst the Observer pattern is useful to being aware of, quite often in the JavaScript world, we'll find it commonly implemen Ted using a variation known as the publish/subscribe pattern. Whilst very similar, there is differences between these patterns worth noting.

The Observer pattern requires, the Observer (or object) wishing to receive topic notifications must subscribe this int Erest to the object firing the event (the subject).

The Publish/subscribe pattern however uses a topic/event channel which sits between the objects wishing to receive notific Ations (Subscribers) and the object firing the event (the publisher). This event system allows code to define application specific events which can pass custom arguments containing values need Ed by the Subscriber. The idea here's to avoid dependencies between the Subscriber and publisher.

This differs from the Observer pattern as it allows any subscriber implementing a appropriate event handler to register F Or and receive topic notifications broadcast by the publisher.

Here's an example of what one might use the publish/subscribe if provided with a functional implementation powering publish() , subscribe()and unsubscribe() behind the scenes:

Learning JavaScript Design Patterns the Observer Pattern

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.