Reactive programming vs Passive programming

Reactive programming has been quite a buzz word for quite sometime. It is often confused with programming in React.js. In this post I will share my understanding of what is reactive programming and when to use it.

Software programming is about implementing a business use cases in a language which computers can understand. High level languages have made programming easier and accessible for everyone. This has allowed us to tackle complex business problems such as e-commerce, health insurance. However, it is important to distinguish complexity into essential and accidental.

Accidental Complexity

Accidental complexity is the complexity introduced in a system by the architecture and programming paradigms. This is generally independent from the business problem.

Consider the following code snippet in Java to read a file:

InputStream fileInputStream = new FileInputStream(FILE_PATH);
BufferedReader bufferedReader = new BufferedReader(
        new InputStreamReader(fileInputStream));
String line="";
while((line = bufferedReader.readLine()) != null){
    System.out.println(line);
}

Following is the code in Python:

with open(FILE_PATH, "r") as file:
    for line in file:
        print(line)

Python achieves the same functionality with lot fewer lines of code. This complexity is not due to any business requirement. Solving such complexity is generally straight forward. In the above case, we can use class composition to reduce the lines of code.

Essential complexity

Some systems are inherently complex and take time to understand. Consider the following system:

delhi-metro-rail-map copy

The above image is a route map of Delhi Metro in India. Looking at the above map, it is difficult to find the exact route from station A to station B. There can be multiple alternative routes and some of them might not be valid. However, a color coded image can remove majority of confusion:

delhi-metro-rail-map

Now we can get a better clarity of how many different lines of trains ply in Delhi Metro. It binds stations on the same line much more clearly. Hence, solving an essential complexity involves finding creative solutions which make the complexity easier to understand. This is where the understanding of reactive and passive programming can help us.

A software is divided into modules with each performing a set of cohesive functionality. I will take an example of e-commerce checkout flow system. Consider two modules, Cart and Invoice such that if an item is added in Cart, Invoice should be update.

CartItem.png

One way to achieve this is to add dependency of Invoice on Cart, such that when Cart updates itself, it updates Invoice as well. Something like the following pseudo code in Cart:

addItemInCart(Item item){
    Invoice.update(item.price)
}

CartInvoice1

Another way to achieve this is to add dependency of Cart on Invoice such that Invoice updates itself when an item is added in Cart. Something like the following code in Item:

Cart.onAddItem(function(Item item){
    self.update(item.price);
});

The above code uses a callback function  which gets invoked when item is added in cart.

CartInvoice2.png

Notice the difference between the arrows in the above two figures. In case when Invoice is passive, Cart is dependent on Invoice. Hence the arrow is near Cart. In case when Invoice is reactive, Invoice is dependent on Cart. Hence the arrow is near Invoice. This is the major difference between reactive and passive programming. In reactive programming, a module is responsible to update itself as compared to passive programming, where other modules are responsible to update the module.

In a fairly complex system, managing dependencies is a critical aspect. Systems with clearly defined dependencies are easy to refactor and understand. For a module, dependencies can be described in two areas:

  1. How the module works?: A module will be dependent on other modules to complete its functionality. In our example, Invoice depends on Cart to update itself.
  2. What does it affect?: A module might affect modules which are dependent on it. In our example, Cart affects Invoice.

Hence a comparison of reactive vs passive programming in these two dimensions results in the following table:

Passive Reactive
How the module works? Find usages Look inside
What does it affect? Look inside Find usages

In case of reactive programming, we need to look inside the code of module to find out how it works as the module is responsible for itself. Similarly in passive programming, we need to find usage of a module across other modules as other modules are responsible to update it.

Dependency.png

Scanning through other modules is a difficult job. Incase the module is accessible publicly, it might not be possible to find out its reference. Hence a benchmark of when to use passive vs reactive programming is the ease of how vs what.

In general, software systems become complex when we don’t know how our modules work. Invoice can be updated by Cart but in future might be updated by  Discounts and Taxation modules. Reactive programming serves us well in such scenarios.

Further reading:

  1. Reactive Programming: Why It Matters
  2. The Reactive Manifesto

 

One thought on “Reactive programming vs Passive programming

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s