Getting Started: Event Driven Programming

Published Oct 20, 2017Last updated Oct 25, 2017
Getting Started: Event Driven Programming

The foundations of events driven programming is modeled on actual human interactions of action and reaction. Just as actions precede reactions, actions(functions) precede events. These functions or methods, as you may call it, are referred to as handlers, because they handle/respond/react to certain events.

But a fair question to ask at this point is: what is an event? Despite how ambiguous this question is, I think it qualifies as a criteria for assessing our understanding of events driven programming.

EDP is language agnostic. This means that we can implement it in any language. However, the example code here uses JavaScript, only because it’s popular and common among most developers.

What are Events?
Events are actions. These are verbs — any occurrence we can identify in our program. Although we are not concerned with most of these events, we will usually create handlers for those that are of importance to us.

Of course, as in reality, just because we don’t respond to every event doesn’t make them uneventful.

Example/Sources of events
1. User interaction: mouse clicks, key strokes etc.
2. Programs: within or from other programs using messages or threads.
3. Sensory IO’s: network connections.
4. Hardware connections: USB connections.

Why should we care about EDP?
Just some of the benefits…

  1. Builds upon Object Oriented Programming
  2. It often leads to better software design
  3. Enhances the building of event driven applications like those that watch changes in appliction states
  4. Improved responsiveness and flexibility
  5. Speeds up processing, since data can be distributed across multiple processors/handlers.
  6. Improves application scalability. You will be able to easily extend your application
  7. Increases loose coupling

Use Cases

  1. AngularJS: the implementation of two-way binding ensures data synchronization between the view and data store via API calls. Controllers play a key role in the event driven design of AngularJS (also for Ember and Backbone).
  2. Flux/ReactJS: Flux builds on the principle of “unidirectional flow” by updating state according to data from the server and spawning events across dispatchers and stores. Yes, it is a model, but an event driven model.

Design Patterns
Design patterns are just a way to write code and they abound. Below are basic implementations of Observer and Pub/Sub pattern to get us started with EDP.

  1. Observer Pattern: a subscription model that provides objects with subscription to events. These objects gets notified when an event occurs, and they act accordingly. Observer pattern shines a lot in developing GUI applications. Most front-end frameworks and libraries, such as AngularJS, are built upon this.

The code below demonstrates observer pattern.

// create an Observable class
class Observable {
  constructor() {
    this.observers = []; // and array to hold all observers
  }
  
  // adding new observers
  register(observer) {
    this.observers.push(observer);
  }
  
  // removing an observer
  unregister(observer) {
    this.observers = this.observers.filter((obs) => obs !== observer);
  }
  
  // emitting to an observer
  notify(message) {
    this.observers.forEach((observer) => {
      observer(message);
    });
  }
}

// new observale instance
const observable =  new Observable();

function observer1(message){
  console.log(`First observer ${message}`);
}

function observer2(message){
  console.log(`Second observer ${message}`);
}

observable.register(observer1) 
observable.register(observer2)

observable.notify('Hello Devs');
// First observer Hello Devs
// Second observer Hello Devs

observable.unregister(observer2); // after unregistering observer2 and we notify next, observer2 will not be triggered

observable.notify('Observing the observer');
// First observer Observing the observer
  1. Publish/Subscribe: similar to observer pattern. The difference is that objects subscribe to topics. An object only gets notified when an event occurs within a topic it is subscribed to. Why would I want to be notified of something I don’t need?

You’ll realise this scales better than observer pattern. Pub/Sub is mostly used on the server side.
Below is a basic implementation of pub/sub.

// Create Publisher class
class Publisher {
  constructor() {
    this.subscribers = []; // and array to hold all subscribers
  }
  
  // method for adding new subscribers
  subscribe (topic, subscriber) {
    this.subscribers[topic] || (this.subscribers[topic] = []);
    this.subscribers[topic].push(subscriber);
  }
  
  // method for removing subscribers
  unsubscribe (topic, subscriber) {
    if (!this.subscribers[topic]) return;

    this.subscribers[topic] = this.subscribers[topic].filter((sub) => {
      return sub !== subscriber;
    });
  }
  
  // method for notifying subscribers
  publish(topic, message) {
    if (!this.subscribers[topic]) return; // return if that topic does not exist
    if (this.subscribers[topic].length <= 0) return; // return if there's no subscriber to that topic
    
    this.subscribers[topic].forEach((subscriber) => {
      subscriber(message); //executing each subscriber in the topic
    });
  }
}

const publisher = new Publisher(); // creating a publisher instance

function welcomeMember(member) {
  console.log(`Hello ${member.firstname}!`);
}

function showConnectionStatus(status) {
  console.log(`Internet conection is ${status}`);
}

publisher.subscribe('members', welcomeMember); // subscribing the welcomeMember handler
publisher.subscribe('network_conectivity', showConnectionStatus); // subscribing the showConnectionStatus handler


publisher.publish('members', { firstname: 'Doe' })
// Hello Doe!

publisher.publish('network_conectivity', 'poor');
// Internet conection is poor

Terms to understand

  1. Publisher, Observable, Subject, Dispatcher: The event emitter. This is where every event originates from.
  2. Subscriber, Observer, Object, Listener: The event handlers. Methods are defined to respond to events.
  3. Register, Subscribe: Method for adding new observers to observer's list.
    Unregister, Unsubscribe: Method for removing an observer from observer's list.
  4. Notify, Publish, Emit: Method for sending messages to subscribers.
  5. Messages, Payload: Data sent from between publishers and subscribers.
  6. Channel, Topic: Pub/Sub routes subscribers listen to for data. We can have multiple channels.
  7. Interface: Blueprint event handlers must conform to.

These are common terms in EDP. Some do have multiple names,so it’s good to understand them for different use cases.

Push and Pull Models
Push: The publisher sends all data to subscribers. This may be difficult because you have to make a lot of assumptions about subscribers, which may be incorrect.
Pull: Here the publisher sends minimal data to subscribers. The subscriber sends a callback for an updated data if necessary, and the publisher updates the subscriber with the complete data. The difficulty here is latency. You’ll make multiple calls.

Related Concepts

  1. Reactive Programming (RX): asynchronous programming where we treat data as streams of events.
  2. Functional Programming (FP): declaratively composing pure functions, avoiding shared state, side effects, and mutable data. Concepts such as closures, anonymous functions, and callbacks from FP are instrumental to EDP.

A lot can be done with EDP. From the above, we could go ahead and expand this to include retry and acknowledgement, but I’ll leave that to you. #Ciao

View code on Gist

Discover and read more posts from Joshua Udensi
get started