Design for Continuous Delivery

Continuous Delivery !!!
You must be thinking "AHHH..... yet again another blog for same old topic", but wait, I am not going to talk about any tools and some regular stuff, I am talking here about design and structure. Yes design and structure, which most of the time is the reason for failure or success to achieve Continuous Delivery.
After reading this post you will be able to structure your code to find finite scope of testing for each release. You will get a table like below telling you what is to be regressed and what not.

Module 1 Module 2 Module 3 Module 4 Module 5 Module 6
Functionality 1 Impacted? No No Yes Yes No No
Functionality 2 Impacted? Yes Yes No No No Yes
Functionality 3 Impacted? No Yes Yes Yes No No
Functionality 4 Impacted? No No No No No Yes

You must be thinking how design might impact how you deliver the code, but wait and read the complete blog and then decide yourself how it makes sense and were you following this.

So first of all what do we want to achieve, we want that we can deliver something into production as soon as it is written by developer (and of course tested also). And what are the roadblocks in the path creating a build with all complete features, their integration, testing in different environment, regress, performance and user acceptance.

So we know number of things already when it comes to continuous delivery, Agile, Automation, build pipeline, feature branching..... the list goes on and on. But all this is possible only if you start your project right, you design it and structure it properly.

How to implement proper agile to get a release in production as soon as every week, read my another blog How to Implement Agile Properly

When we talk about continuous delivery we inherently talking about microservices and automated testing. Because if you don't have microservices in your project and its a big monolithic system, you will never be able to test the impact in time. Or even if you build an automated testing system today, it will be outdated very soon and you will not be able to manage all the regression even with automation.

Lets first agree on the fact that monolithic is bad, very very bad. In a monolithic system you fix one thing and risk every other thing so testing has to be done of entire application to be sure. Today might be your project is small with just a few classes but with years of patching and enhancement its going to be an elephant. Even if you have Junits today nobody will manage then in a year if they have to manage test cases of 200+ classes in project.

Result.... you will skip test cases.

So first break your code in number of small maven modules each not having more than 30 classes in it. This kinda projects will be manageable with Junits. Every Project should be atleast 6 modules,

  1. Core
  2. Util
  3. Common DB
  4. Notifications
  5. Functionality n
  6. Integration

Now based on your project it can have one additional WAR module or Main module is its self deployable. Also here functionality projects can be from 1 to n. Ideally if you deploy it as microservice n should have less than 5 or good if even 1.

Lets take an example of application to manage travel request, requirement is simple, "As an employee I should be able to raise a travel request"

So for this application you will have just one form with few fields and few tables. Now create modules as mentioned above. In first iteration you have one functionality module (lets say request), now you need to implement another functionality that request should be approved by Manager.
You create another module (lets say it approval) for approval process and deploy it.
Next month you got another request to notify manager for new submitted requests, you create an integration of request module and notification module and its done, now you see for this change you know there is no commit in any module other than Notification module and request module so your scope of testing is limited to that functionality only.

Next you get request to have admin module to review and amend any request, you create another functionality module and again its scope has no impact on existing modules so you can deliver it as soon as you test.

If a change comes in, you implement it and based on its commit and your SCM logs you can fill up the above table to assess regression impact now.

To check how to break an application in small modules, check my next blog, How to Shatter your Application

Comments