Blame it on monoliths - Part 2

Moving to micro-services will solve all my deployment and maintainability issues.

Wed, 30 Oct 2019

Banner

Story Behind this Post

This post is further discussion of the post that can be found here where we discussed two most prominent features about micro-services and tried to explain how they are not exclusive to Micro-Services actually they are attributes that can be achieved with good architecture and following basic SOLID principles.

Link to the first post of this series is here Blame it on Monoliths - Part 1

In this post(Part 2) we will take an example of an application that looks like have a micro-service architecture and try to see how having a micro-services alone will not help with Deployability and Maintainability of the software.

The example in this Post is inspired from the Book Clean Architecture by Robert C Martin. It’s a great book and must read for any developer to understand the basic principles of Software Construction. So all the credit for this post goes to the book.

Flight Finder System (Flight Finder)

This system knows about many airline companies, and allows customers to search for flights. Let’s assume that the customers select flights based on a number of criteria, such as date/time, cost, luxury. We wanted our system to be scalable, so we chose to build it out of lots of small micro-services. We subdivided our development staff into many small teams, each of which is responsible for developing, maintaining, and operating a correspondingly small number of services.

Banner

Here are few Micro-Services we have in our fictitious architecture and their purposes from the above diagram.

  • FlightFinderUI is front end application used by customers to search/book flights using our system.
  • FlightSearch Service is used by Flight Finder UI to search the flights available for provided criteria and combination of User preferences.
  • FlightAggregator Service is responsible to scan through various supplier inventories and find all suitable flights for provided user criteria.
  • FlightSelector service takes user criteria of cost and time and then further filter down the available flights.
  • FlightBooking service order the selected flight for the Customer and communicate the booking to Airline system.

The FlightFinderUI is front end used by the customers, who use mobile devices/web browser to search flights. The FlightSearch takes the user selection criteria as input from FlightFinderUI and call FlightAggregator service which then examines the inventories of the various Airlines and determines which flights are available for the user and then return results back to service FlightSearch which keep it in some local cache.It then passes all the flights available from different airlines to the Service FlightSelector. The FlightSelector service takes the user’s criteria of cost, date/time, luxury, and so forth, and then call the UserPreference service to fetch additional user preferences and further filter down the list of available flights. Then it returns results back to FlightFinderUI. Then customer select one of the available options and FlightFinderUI invokes the FlightBooking service, which book the appropriate flight.

Warning: I am no Architect and lot of people may not like the architecture but keep in mind this architecture is fictitious and used for example sake only.

Marketing Happens

One bright and cheerful day, the marketing department holds a meeting with the development team. In this meeting, they announce their plans to find flights for Kittens customers can look up flights that are Kitten friendly.

I am just making up this requirement for example sake. - You must have figured that out already :)

Only one of the Airline Company have agreed to provide this service but others will follow in future. Some airline companies may decline. Some of the passenger will have Cat allergies so a Flight that has been used to deliver kittens should not be selected for customers who declare such allergies and so on.

What needs to change

How many of those services will have to change to implement this feature? All of them. Clearly, the development and deployment of the Kitty feature will have to be very carefully coordinated.

In other words, the services are all coupled, and cannot be independently developed, deployed, and maintained.This feature request involved cross cutting concerns that run through the most the services. How we could have made such feature request least painful or more manageable?

SOLID to the Rescue

Let’s assume for a moment we don’t have micro-services we have a monolith with component based(Plugin based) architecture instead of multiple services we have multiple components that make up the system.

Component is something equivalent to DLL in .net world, jar in java world or GEM in Ruby world.

Specially if we look at the Open Closed Principle it would have suggested us to create a set of classes that could be polymorphically extended to handle new features.

We should create a abstract class to define the behavior of FlightSearch class and then we implement classes for Passengers and Kittens that will be polymorphically used in place of the abstract FlightSearch class.

To add new feature for Kittens we will add new component(DLL/jar) that override the Abstract FlightSearch class. So The new feature for kittens has been placed into a Kittens component. These two components override the abstract base classes in the original components.

So we will end up having two components Passenger and Kittens both follows the dependency rule dictated by SOLID principles. The FlightFinderUI will have a factory which will decide which override of Base abstract should be created to handle a request depending upon if user is searching for Passenger flight or Kittens Flight. If we need to add another feature in the future we add another component that override the abstract base class for FlinderFinderSearch.

This way in future if we add new feature we just update FlightFinderUI to load another DLL dynamically so the factory can crate instances of it.But nothing else needs to be changed. Rather, a new jar file, or Gem, or DLL is added to the system and dynamically loaded at runtime.

So if we have to show the Component diagram for the FlightSearch.Note: I omitted other classes from the digram for brevity. It will looks something like below. The empty arrow head show inheritance(Abstract override). Red rectangle shows the component boundaries.

Banner

So the abstract base class for FlightSearch is overridden polymorphically for Kittens and Passengers. If in future they want to find flights for Parcels also they can add another polymorphic override for the Parcels.

In this way we can add new functionality to the system by just adding new code instead of editing existing code. This is what exactly the Open Closed Principle if this this principle is followed new changes can be made with least pain.

It doesn’t even matter if you are using Micro-Services or just using plain component or plugin based architecture The effort needed to add new feature will be similar.

What we learned

What we have learned is that architectural boundaries do not fall between services. Rather, those boundaries run through the services, dividing them into components. To deal with the cross-cutting concerns that all significant systems face, services must be designed with internal component architectures that follow the Dependency Rule,

Here is what our micro-services diagram will look something like if we stick to basic SOLID principles.

Banner

See you later

This post was part of the 2 post series. In the first post we discussed the Two Major benefits of the Micro-Services in details and how they are not exclusive to the micro-services and then we discussed the theory about the what core SOLID concepts actually help with Maintainability and Deployability of the code. Then in this post we looked at the example using an interesting application. It’s time for me to say goodbye will see you soon with some other post. Enjoy your life and Be humble. I will see you soon new post.

Loading...
Ranjeet Singh

Ranjeet Singh Software Developer (.NET, ReactJS, Redux, Azure) You can find me on twitter @NotRanjeet or on LinkedIn at LinkedIn