When writing software, it is important to keep you organized and focused, losing focus or vague understanding requirements will endup in a bad written system in the best case.
If you have got a large body of work that needs to go into production there are lots potential things that can go wrong. When you shrink that change down, make it very small, is much less to go wrong. Also, if something goes wrong it is usually easier to identify and fix.
Having a well defined direction with milestones it is an important process when writing software, doing small, independent parts, integrating them and deploying (CI/CD) will at least save hours of resolving conflicts.
Keeping your changes small have other arguments also, imagine that your colleague just requested you to review a 5K lines of code, how would you feel about this? It may take hours until you fully understand what’s going on there. Keeping pull requests small make them easy to understand.
Migrating database isn’t an easy task do to, what happens when you are migrating Gigabits of data and your migration fails? Do you continue with code deployments or revert your patch? It easier to prepare your database first and then deploy code changes. When doing this two tools are required:
- Build small, focused changes
- Be careful about DB data structure backward compatibility
What happens if your database was deployed but your code deploy failed? Is your software down until you will fix and redeploy? Keeping database migrations separated from code makes deployment less riskier.
If you are using relational database, Martin Fowler has an article that describes some techniques for database migration: https://martinfowler.com/articles/evodb.html
A book that I would recommend is Refactoring Databases: Evolutionary Database Design
Look at your feature as an mechanism composed from several small gears, a gear representing a piece of functionality that can be extracted and replaced with another one. Keeping your gears separated makes easier their replacement, you are safe when requirements are changing during development, which we know happens.
Agile is a methodology that describes how we should react to changes, changes are something normal, everything around us changes, we should adapt and be prepared to changes.
Another idea from Agile is that things should be build incrementally, you can’t make the perfect software in one step, iterations are required.
We were learnt to predict and avoid looping when doing development, nowadays this isn’t true anymore, we should listen to people requirements, monitor our system and iterate on making it better.
Usually when writing software, after the design was approved with the team, I take a breath for few minutes trying to split small parts in smaller parts.
When splitting it, in my head I start with an empty space where I’m adding pieces of puzzles, initially puzzle parts are without an image, just with black borders. As I write code and my pull requests are accepted, merged and deployed, puzzle pieces are completed with black and white images without being connected between them. An image from a puzzle piece represents functionality.
As more pull requests are merged, images from puzzle pieces start having colors and some pieces are connected.
When feature is ready, all puzzle are connected, image is colored and shiny, tests are green.
Using images to represent this:
I would recomend to watch Martin Fowler presentation about Continue Delivery: