Agile software development is not just about agile principles and practices. To be successful in releasing software that positively impacts end-users, addresses technical debt, and deploys reliably, the development team must also consider their agility-driving coding practices and architecture standards.
An even more important consideration is at stake for technology organizations. As hard as it is to develop software, it’s even harder to deploy enhancements and upgrades regularly over an extended period. Devops CI/CD and IAC (infrastructure as code) practices partially address one critical factor as the automation enables reliable and repeatable ways to deploy applications. Add in continuous testing, and development teams have a way to validate that code changes don’t impact existing functionality.
However, as applications get older, the original developers move on to other projects and sometimes other companies. When new developers join the team, they must learn the software’s architecture and understand the code before they can reliably and efficiently change it.
Furthermore, developers who build applications often want to develop new ones. It might feel comfortable and safe to stay attached to the applications you develop but being tethered to your code is not healthy for your career or the organization.
The best way to move on to new and exciting software development initiatives is to make your architecture, application, and code easily supportable by other developers. Agile teams and developers must establish and enforce coding practices that sustain ongoing software development.
1. Don’t reinvent the wheel
The first rule of coding: Don’t code something that doesn’t need to be coded! How?
- Consider asking questions about the requirements. Why is a feature important? Who benefits? More specifically, explore noncoding options to solve the problem. Sometimes the best solution is no solution at all.
- Has someone in your organization already coded a similar solution? Perhaps there is a microservice that just needs an enhancement or a software library that needs a minor upgrade? Be sure to look through your organization’s code base before coding something new.
- Are there third-party solutions, including affordable SaaS tools or open source options, that meet minimal requirements?
- Have you looked at open coding repositories such as GitHub for code examples and snippets that meet your organization’s compliance requirements?
2. Consider low-code development options
If you do need to code a solution, then perhaps alternative low-code platforms can enable developing the capabilities more efficiently compared to coding in development languages such as Java, .Net, PHP, and JavaScript.
Low-code platforms such as Caspio, Quick Base, Appian, OutSystems, and Vantiq all provide tools to develop applications with little code and sometimes even without coding at all. Each platform specializes in different capabilities and is thus suitable for a specific class of applications. Caspio, for example, makes it easy to embed forms and workflows into websites. Quick Base has robust workflow and automation capabilities, and Vantiq’s event-driven architecture is suitable for IoT and other real-time data applications.
There are times coding is required, but developers should also be proficient in one or more low-code development options and consider them for appropriate use cases.
3. Automate testing
Beyond writing code that fulfills the requirements, one of the most important things developers need to do is to test it. Test-driven development practices and automated testing tools have matured, and development teams should include unit, regression, performance, and security testing as part of their agile estimates.
In addition to having tests to validate builds and releases, these tests also help make the code more supportable. Tests are documentation and establish a contract of how the code is supposed to behave. When new developers join teams and inadvertently implement a bad change, continuous testing halts the build and provide meaningful feedback to the developer in order to quickly address the issue.
4. Externalize all configuration parameters
There should be no excuse for developers to ever hard code system-level settings, usernames and passwords, or other configuration information in the code. I’ve seen developers take shortcuts while developing prototypes that find their way into production environments. In today’s architectures this should never be done. Hard coding is not technical debt but a lazy, irresponsible coding practice that can have significant consequences. If code becomes accidentally accessible, it creates a security vulnerability if endpoints or access credentials are exposed.
Going one step further, when legacy code is being worked on, addressing any hard-coded configurations and parameters should be a non-negotiable technical debt priority.
5. Follow naming conventions and include comments to make code readable
I once worked with an incredibly talented developer who didn’t know English well and wasn’t the best typist. He would instantiate objects with names like a, b, and c and then create local variables named zz, yy, xx. He would commit to cleaning this up before the release but rarely followed through.
You shouldn’t need to have pair or mob programming instituted to recognize this is a terrible practice.
Teams should adopt naming conventions such as Google’s JavaScript Style Guide and Java Style Guide and commit to commenting code at least at the modular level and ideally at the class level. In addition, organizations should consider using static code analysis tools that provide feedback to developers when code needs refactoring for structure and readability factors.
6. Check code into version control frequently
If you’re not checking code into version control on a daily or more frequent basis, it can create conflicts and other blocks that impact the team. One small mistake can cause agile teams to miss their sprint commitments or create additional work to resolve dependencies.
Teams should agree on conventions for checking in code that’s not ready for production. Conventional approaches include feature flags and Git branching.
7. Avoid coding heroics and complexities
Most developers I know became professional software engineers because they love solving coding challenges. Coding is an art, science, and craft, and better developers seek thought-provoking coding assignments and elegant implementations.
Except there’s a gray line between solving challenging business and technical tasks versus coding heroics that leave the next developers with code that is hard to understand and complicated to maintain.
For those of us who have been coding some time, we remember the convenience of Perl one-liners or using nested templates in C++. Sometimes there are good reasons to use these approaches, but if a new group of developers doesn’t understand these techniques it’s more challenging to change the code. Sometimes simple but less elegant coding practices are better.
Driving agility in agile software development
The rituals embedded in scrum and agile development, including commitments, standups, sprint reviews, and retrospectives are now proven practices to enable team collaboration and drive successful implementation. But to demonstrate agility over a long time, developers must take on responsibilities and coding practices that enable longer-term support and extendibility of the code they develop.
Development teams must take a critical view of their coding practices. It’s not just good enough to demo and release today; it’s also crucial to enable others to easily maintain the application and code.