A couple of months ago, we ( the development team that I’m part of ) have been asked to deliver a new epic and actually be deployed in production in less than 2 months. The epic was pretty massive, a complex UI needed to be developed, a new microservice was required to interact with other components from the ecosystem, and a new database needed to be set up. A proper estimation of that epic would have been around 6 months of development and testing considering the existing available resources ( developers ).
Management Team after dropping the bomb to developers ( not to be taken seriously )
Just like any developer, my first reaction was “the team will not be able to this”! At least, not without interfering with the work-life balance.
Disclaimer: the entire team was able to actually deliver the epic in the limited time window without spending a minute of their personal time-off.
Does this story sound familiar? I think that every developer went through this kind of situation at least a couple of times throughout his career. Some of them may have successfully delivered the epic on time while some others were not so lucky. Here is how we did it:
I knew that by using “traditional” approaches we are not going to make it on time, so inspired by “Build a tower, build a team” by Tom Wujec, as the tech lead, I’ve decided to use prototyping to structure the required work.
“Build a tower, build a team” by Tom Wujac
After everyone calmed down ( 10 minutes later ), we started to devise a plan of action and we came up with this:
- we needed to be as flexible as possible so we used Kanban during this period;
- NOT writing any automated test during the development phase;
- map out all the requirements and dependencies;
- go for an incremental approach and use prototyping as much as possible;
The result was impressive, the epic has been delivered on time, the number of bugs was small and the features are more stable than ever. Of course, due to the short development cycle, we have accrued some technical debt ( not using the finest code structures, lack of automated tests ) but we were able to circumvent that in the upcoming weeks.
Just like any development process, we started by putting down on paper all the requirements that were mandatory to complete the epic. To give an idea of what of the requirements, the goal was to display on a web interface customer activity data across multiple days/months. Having a clear picture of the business requirements in our mind we then started by designing a technical solution.
New Epic’s Architecture
We already had a couple of components in place:
- Authentication / Authorization Service
- Customer Data Service
- System Data Service
So, in order to complete the epic we needed to build the other 3. Nothing very complex compared to other problems but what I would like to point out is the way that we decided to build this epic.
Developers, in general ( that includes me as well ), have a tendency of not showing up work that is incomplete to anyone else. “Let me finish it and then I’ll show you how it works”, sounds familiar? During this epic, we tried to break this pattern by using prototyping.
How Does Prototyping Works?
At first, you aim for the Minimum Viable Product ( MVP ) that can be considered minimal progress. “I need a new web interface with a graph, 5 buttons, a calendar, and 2 dropdowns menus”! Great, your first MVP would be a blank page.
Yeey, our first MVP
I’m not kidding! We started by creating, packaging and deploying a blank page to one of our acceptance environments.
Why? Because later, we will not have to worry about packaging and deploying. To get this done without worrying about the code is amazing.
The best part is that each component can be prototyped in a completely independent way without setting up too many dependencies between them. “A new collector service”? Brilliant, we deploy an empty server to our environment. The same for our database.
In the meantime, we could already start on providing endpoints to connect to on the other services ( auth, customer data, and system data ).
The UI needs to interact somehow with the Collector Service ( CS ) so the next logical step would be to hardcode some dummy data into the CS endpoints. By this, we avoided any integration dependency between Frontend and Backend. The UI can be developed independently and after each small improvement ( new button, graph or dropdown ) a new version would be deployed to the “acceptance” environment. Like this, we also shortened the feedback cycle between development and business.
At the same time, the CS would be finished piece by piece swapping out the dummy endpoints with the real deal. Calling the Authentication Service, gathering customer and system data, and even dealing with the persistence layer, everything was replaced in an incremental fashion but always making sure that the changes don’t break the existing code.
What’s the Difference between CI/CD and Prototyping?
I think that both practices share the same ideas underneath but the key difference between them is that CI/CD usually deals with complete features whereas prototyping allows having incomplete features during the development cycle.
- write TESTS while prototyping; it doesn’t matter if you are a fan of BDD or TDD, tests will always pay off! Prototyping helps with having a steady increase in the software complexity but once you hit the critical mass, things will start going sideways without tests;
- parallelize as much as possible; the key of successful prototyping is running into at least dependencies as possible;
- aim for the smallest deliverable unit; it doesn’t matter if it’s an empty page or a simple button, prototyping is all about tryouts of simple things;