I’m a big fan of Agile. Not because I hear cool people talking about it or because I make money writing about it. I’m fan of it because it works.
Many would debated that claim. I’m sure if you searched the blog-o-sphere, you would find claims for and against Agile’s results. Everyone from professional Agile coaches to project managers to engineers usually have an opinion on the topic.
But one thing I’ve noticed as I have read more and more about Agile, the more and more I realize most people still approach Agile as a fixed process for project management, instead of a mindset.
Now, I’m not gonna go all “Budda” on you or anything. I simply want to show that Agile is a NOT just a prescription of steps to increase your team’s output. Its NOT a list of dos and don’ts. Its a way of thinking about how to tackle complex, ever-changing problems.
To me, one of the keys to an Agile mindset revolves around the idea of Early Feedback. When a product owner interfaces with a customer, and then involves an engineer only after the fact, things get lost in the middle. When all three parties meet, there is better understanding because all three people can quickly clarify a statement, poke holes in assumptions, and ask questions without much back and forth.
When an engineer finishes a story, but no one else looks at the final feature before it goes to production, there is a good chance something will be missed (even if its the difference in where a button is placed). With early feedback, you can deploy to a stage environment and have a user review the change for final acceptance. Or even better, a developer could spot a disconnect between an implemented feature and the requirements in the story. Early feedback between users and engineers, between engineers to other engineers, and engineers to product owners, all lowers the risk of deploying bad software.
Capturing early feedback allows you to also iterate quickly instead of waiting months before finding out something is indeed broken. Iterative thinking frees your team from thinking too far down the road or getting caught up in yesterday’s mistakes. You can’t predict every feature request you will get next month, but you can focus on correcting or improving your existing solution in whatever way it needs to change.
Iterative thinking helps you to focus on what you need to do today, finish by this week, and prepare for next weeks coming work. Instead of thinking of what your system looks like by the end of the year, you can focus on how to improve your system to look better by the end of the week. Don’t get me wrong though – you should have an idea of where your system is heading. You just don’t need to plan every aspect of it right now. You might discover something in three weeks that changes that direction. And in Agile world, not only is that OK, its expected.
Continuous integration tools have become staple to the software development process. Jenkins, CircleCI, Traves, etc. all help to make sure that you are maintaining quality as you build a software system. The Agile mindset takes this one step further and says that in the same way you have automated, systematized ways to validate your software quality is high, you should have the same for your process and team.
An Agile mindset would say you can always get better. An Agile team should never be stagnant or stationary. That being said, don’t fall for the trap that velocity is the only way to measure improvement. That is silly. I can easily increase story point estimates or make tons of small point stories to do that.
There are many other ways you can get better as a team. You can always communicate better; you can always write better code than you did last week; you can always find better ways to organize your stories and backlog. A great way to measure this is to use tools like retrospectives along with velocity or cycle time metrics.
A Working, Shippable Product
The last thing I think that is crucial to an Agile mindset is that you aim to have a working, shippable product at the end of each iteration. Now, again, I’m not saying that you should therefore blindly deploy software after each commit to master or after the first prototype is complete (though some groups do take that approach). What I’m saying is that you shouldn’t have broken, incomplete work that you hope to clean up later. It doesn’t have to be perfect, but it does need to do what it says its supposed to do after a story is completed.
Agile Mindset When Coding
I know, I know. Lots of vague or high-level concepts again that don’t help you write better code. But seeing, that part of the reason I started this blog is specifically to do that, lets actually see how some of these ideas can be applied to help you in your day-to-day code process.
Lost in Too Much Change
How many of you have seen PRs that have 1 commit with +800, -10 lines that simply said “new feature”? Or how many of you have known co-workers who complain that after a days of work they had to start over because they got to place that couldn’t return their code to a working state? I’ve been guilty of both and every time its because I tried to change too much too quickly and got lost. It also cost me a lot of development time.
A better approach is to treat your individual code-writing process like a micro-version of the entire software development lifecycle. But how do you do that?
Break down the feature to specific requirements, isolate the code you need to change (and its associated changes), and slowly start to put the pieces together. The whole time, you should be keeping your tests green and making a commit after every refactor and code change that was meaningful and holistic.
By thinking about the user story you have to implement as a micro SDLC, you can think of each meaningful change you make to meet story requirements as its own small testable unit. This has several benefits, some of the biggest being that if you get confused, you always have a good place to go back too. Additionally, you will likely find you have more time to commit some changes, step back and reflect on those changes. Where they simple? Could you have named something better? Could you have used a better pattern? When everything is swirling in chaos and your only hope out is to “make it all work again”, you can’t reflect.
Make it work, make it right, make it fast. This is a common phrase you have likely heard before about how to write code. In truth, there is a lot more to it, but the approach is solid.
Get something working first. Don’t spend too much time on making it “right” – and especially not perfect. Once you get it working and have appropriate unit tests, you can focus on getting it right. Refactoring pieces around, renaming things, etc. Once all of that is done, you focus on making it fast. Each set of changes is all about making small iterative and measurable changes.
Commit Shippable Changes ONLY
During this process, make sure you only every commit shippable changes. By that, I mean that your software actually runs and passes tests. Do your best to always verify this locally first, but you should also have automated tests that run on every pull request or committed change. That way nothing gets through the cracks.
The benefit of this is you always have a fall-back point. If you follow this advice along with small commits, you should never find yourself so deep that you can’t get out of “refactor hell”. Just realize you took the wrong approach and revert to your previous commit.
Ask For Early Feedback
Lets say you’ve finished up all the requirements for a story and think its ready to go. Your only though is if you should “tidy up” a few places to make the code more readable – ie comments, renames, more test cases, etc. What most developers do here is they will spend a lot of time trying to figure out what those tidy-up tasks are. What I think you should do is open a PR, ask for a review or too, then take a break 🙂
Chances are, a few different pairs of eyes will be able to spot the places you need to tidy up much, much faster than you will. They don’t have the same context for everything you and thus will approach it from a different perspective. You get added benefits of having someone double-check that what you implemented indeed matches the requirements – ie telling you earlier that its not as ready as you think and you can spend your energy on that instead.
All of this is to really show that you can apply the Agile framework to more than just the SDLC. You can apply it directly to your code writing process if you think of it as a mindset rather than a process. Be on the lookout for a step-by-step example (complete with code) of how I’ve done this on a real feature.
How have you applied an Agile mindset to your code?
Till next time!