A fundamental part of delivery competence is creating the space and environment for producing quality code output.

  1. Previous: Plan
  2. Next: Continuous Integration

While “good code” can be subjective, it is useful to think about what “ideal” code practices are and work backwards to understand which practises are needed in your organisation’s context. This overview provides guidance for assessing and developing team competency as they seek to produce “better” code.

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” - Martin Fowler


Ideal code should have the following characteristics:

  • Maintainable

    It should be possible to confidently change the code without undue concern for which developer makes the change or how they will do it. This ensures the wider change capability is resilient: any developer can make the change, and tools are in place to facilitate the change.

  • Stable

    It should be possible to confidently change the code without introducing new errors, issues, or security vulnerabilities. This helps to make change time more predictable, and minimises time spent in quality control cycles.

  • Appropriate

    Code changes should be tailored to the problem being solved, and not over- or under-engineered. While part of the responsiblity for an appropriate solution lies in the planning stage, there must be commensurate attention to coding competency to ensure that implemented solutions match the expected design.

Developing competency

To achieve the objectives outlined above, consider the following suggestions:

  1. Deploy collaboration tools

    Establish communication tools for the team. This may be a Microsoft Teams Team), a Slack channel, Gitter Community, or other similar collaboration tooling.

    Persistent chat is a key feature which enables participants to easily contribute to ongoing conversations and then “catch up” on latest communications. This is particularly useful in situations where collaborators work different shifts, work in different time zones, or return from sickness and annual leave.

    Maturity indicators

    • Communication tooling used frequently by all members of delivery teams
    • Automated “bot” notifications from CI/CD or other systems
    • Team members “chip in” to conversations as necessary
  2. Get people talking

    Cross-discipline discussions help team members to understand the challenges and complexities of complementary delivery roles, identifying inefficiencies and addressing potential issues with minimal waste. Organise appropriate team ceremony to ensure all team members share the same vision and delivery priorities.

    Maturity indicators

    • Regular diarised delivery meetings
    • Good meeting attendance with contribution from all attendees
    • Issues are identified early, often through meeting discussions, and not through later quality control processes
  3. Repeatable development environments

    Alongside environments for delivery of a system under development should be the development environments themselves. These are the desktop environments where developer tooling is installed, including IDEs, SDKs, and local servers.

    Being able to reliably create these environments is key to being able to respond to change, particularly where delivery resources are moved between projects and need to minimise “context switching” time (the time for a resource to end a task in one delivery and begin a task in a new one). Likewise, securing development environments with appropriate secret management systems helps to establish secure app development behaviours which flow onward through the delivery journey.

    Maturity indicators

    • Developer desktop provision is documented, scripted, or automated
    • Clear secret management processes
    • Consistent tooling across development team (same IDE, framework, and SDK versions)
  4. Enabling isolated execution

    Software is often dependent on external systems to deliver key functionality which then may be incorporated into development and test environments. Mock frameworks allow these external dependencies to be replaced with lighter, simpler dependencies which allow software under development to be executed in isolation, without these dependencies in place. While mocking data, relationships, and security boundaries can be difficult, this is often preferable to maintaining these alongside an external system which defines them, and which may be impractical to deploy to development environments.

    For complex systems it is not viable to have all dependent systems available in a development environment, and abstractions alongside mocking frameworks must be used to validate system functionality.

    Maturity indicators

    • Systems under development are not reliant on external systems or data to run and test
    • Software abstractions are in place to enable mocked dependencies
  5. Early code validation

    Perform code validation as early as practically possible in the delivery lifecycle to help developers maintain code quality. Depending on the technology being used, it may be possible to fail builds or prevent commits where:

    • Code style conventions are not met
    • Documentation is missing or incomplete
    • Analysis tools (security, performance, complexity) identify issues
    • Commit reasons are provided but do not meet a required format

    The earlier these are caught, the more efficient the team will be delivering value.

    Maturity indicators

    • Code style/convention/hygiene checks are run prior to code commits
    • Documentation is automatically generated from validated code comments
    • Developers cannot identify who wrote code based on style and formatting
    • Release notes are automatically generated
  1. Previous: Plan
  2. Next: Continuous Integration

Reading matter

The following books are recommended to help develop competency in this area:

Book cover art for Refactoring: Improving the Design of Existing Code
Refactoring: Improving the Design of Existing Code

Martin Fowler

Learn about the art of refactoring code from one of the foremost authorities on software development. This is a great introduction for those who aren't familiar with refactoring code and who want to understand what clean, functional code looks like.

Edit this page on GitHub

The content on this page is published under Open Source licenses via GitHub. To submit issues or provide feedback please visit the repository.