Tuesday 28 May 2019

Local Microservices: Object Orientation Behaviour Coupling Problem

This is the first in a three part series on looking at creating "local" microservices.

What I mean by local microservices is pass by reference microservices running in the same process.  Right now I see microservices similar to the original EJB 1.0 specification.  All calls between the EJBs were remote, just like microservices are now.  Due to remote call overheads, the EJB 2.0 specification brought in session (local, pass by reference) EJBs running in the same process.

Now, before getting to local microservices, we need to look at identifying the Object Orientation behaviour coupling problem.  This to me, identifies a big problem that microservices resolve.   It is also the reason enabling local microservices.

Part One: Object Orientation Behaviour Coupling Problem

Structurally Object Orientation joins objects together in a very nice graph. These typically look something like the following:


These graphs represent the object relationships in your application.  Each line is a field reference to another object.  This, for example, allows modelling your personal details to have addresses, phone number and various other objects containing information.

However, I can't call an object reference.  I use the object reference to access a method on the object.  Behaviour of your application actually follows the method calls.  In other words, program control follows method calls on the thread stack.  Yes, the object references make methods accessible to be called, however the methods calling each other is how behaviour of your application is achieved.

So, we can just draw the above graph with the methods calls, right?  No, the method coupling is a lot more complicated than just an object reference that varies at most by type (see Inversion of Coupling Control).   Methods have:
  • a particular return type
  • a name
  • varying number of parameters with differing types
  • varying number of exceptions with differing types
  • thread to execute them
Drawing a simple line between objects to represent behavioural relationships (program control flow) does not respect the method coupling complexity.  In the object structural graph, changing a line is simply changing the reference (memory address) to another object.  Yes, restrictions apply based on the type of object referenced, but it is a single address value that couples the two objects into a structural relationship.  This is not the case with methods.

Each method call is a different shape.  In terms of object structural connectors the shape of the object reference is object type and memory address.   This is consistent across all object references.  However, for methods the call (connectors) are different shapes due to the above 5 aspects.  In other words, one method may have 1 parameter, while another has 3 and throws 2 exceptions.  The shape of each method call connector varies significantly.

Drawing the behaviour diagram of object method calls is more akin to the following:


Each call (connector) between the methods is a different shape, just like a jigsaw.

We piece objects together into a jigsaw to achieve the behaviour of the application.  This is why refactoring your application is so difficult.  It's like trying to move pieces of a jigsaw around to make a new picture.   We end up having to change the pieces significantly just so they even attempt to fit into the new picture.

It is also the reason, I believe, why object orientation never provided that ideal class re-use.   Re-using objects is like trying to re-use jigsaw pieces of one puzzle to complete another puzzle.   Now if the puzzles are somewhat alike, you can kinda jam them together.   However, more often than not you have to change the piece (object) to fit into the other jigsaw (application) losing re-use.

Hence, the method coupling problem creates a significant behavioural coupling problem in monolithic Object Oriented systems.  Refactoring is an expensive exercise, as its not redrawing lines between nice round objects.  Refactoring is reshaping pieces to fit into a new jigsaw picture.

Now I can continue the analogy further with much of API development attempting to standardise jigsaw pieces and finding generic pictures that represent majority of systems.  However, I'm hoping you can join me in seeing that much of Object Orientation behaviour coupling problem is not with the objects but rather the use of methods.

And yes, for Object Orientation purists, Object Orientation is more about loosely coupled message passing.  In other words, languages such as Erlang may be more closer to what the intention of Object Orientation really was supposed to be.  However, my focus here is the "mainstream" understanding of Object Orientation being objects and methods.

Stay tuned for my next part on how microservices are helping with relieving the Object Orientation method coupling problem.