You can’t scale crappy code.
Code Quality Abstract
Code Quality is one of the four core values of SAFe. For the enterprise that depends on software, attention to quality of code is as important as attention to any other engineering or business matter. The enterprise’s ability to deliver new functionality with the fastest sustainable lead time, its ability to successfully execute large development initiatives, innovate, and react to rapidly changing business environments – all depend on the endemic quality of the code. This article describes six specific, proven Agile software engineering practices that help Agile “Define-Build-Test” Teams assure systemic quality of code. In addition, the collaborative nature of these practices and a focus on frequent validation via fast feedback create an emergent culture wherein software engineering and software craftsmanship are key business enablers.
Why The Focus on Code Quality in Such a Big Picture?
It should be self evident that endemic code quality is vital to any business that depends on software, but it becomes even more critical as the enterprise scales software development. There, the cumulative effect of even minor errors and misassumptions can create dire consequences at the system and enterprise level, with the potential for major, negative impact on customer deployments. So while much of the focus in SAFe is at the Program and Portfolio levels, and it is perhaps fair to assume that Agile Teams generally create high quality code, it is both necessary and useful to include and prescribe current Agile software engineering practices that help teams achieve the highest-level quality. In this “uber article”, we provide a summary of these practices, some of which link to additional, “behind the Big Picture” depth and breadth articles.
Business Benefits of Code Quality at Enterprise Scale
Of course, achieving high quality code is serious work that requires ongoing training and commitment, so before we begin, it is useful to consider some of the important business benefits that can be achieved when Agile teams and programs develop and deploy really high quality code.
- Quality products and services. Low defect density software products and services provide higher levels of customer satisfaction, better returns on investment, and higher confidence for business partners.
- Predictability and Integrity of the Software Development Organization. Without reliable control over system quality, it is impossible to plan new business functionality or understand development velocity. This creates a lack of trust with our internal business partners, and the potential negative pride of ownership on the part of the team, which is de-motivational and wastes human capital and potential.
- Scalability. When the code clearly expresses design intent, exhibits simplicity, and has supporting integration and test infrastructure, adding more teams and functionality will result in more business value delivered. Otherwise, adding more developers and testers slows the enterprise down and creates unacceptably high variability in quality and release commitments.
- Velocity, Agility, and System Performance. Higher code quality fosters better maintainability and enhances the ability to add new business functionality more quickly. It also enhances the teams ability to maintain and enhance critical nonfunctional requirements including performance, scalability, security and reliability.
- Ability to Innovate. Innovation occurs in the confluence of smart, motivated people and the environment in which they operate. High code quality creates a fertile, technical environment where new ideas can be easily prototyped, tested and illustrated.
Six Agile Software Engineering Practices for Achieving High Quality Code
SAFe is built on a decade long evolution of better software engineering practices, driven primarily by the success of innovative Agile methods. When it comes to the code itself, Extreme Programming has led the way. In addition, the evolution of lighter weight modeling techniques, have provided a means of reasoning about really big systems in an Agile, and yet fully comprehensive and comprehendible, manner. Together, we largely have what we need now, so it isn’t necessary to invent much of anything new, rather we just need to apply what we have learned in a systematic and disciplined manner.
In the following sections, we’ll describe a set of six comprehensive Agile software engineering practices (summarized in Figure 1), each of which contributes materially to the code quality of even the largest software systems.
Some of these practices link to background articles on SAFe, each of which is designed to provide more specific guidance to the teams doing this important work.
# 1 – Agile Architecture
Agile Architecture is a set of activities designed to support the active evolution of the design and architecture of a software system concurrently with the implementation of new business functionality. One element, Emergent Design provides the philosophical and technical basis for an incremental implementation approach and helps manage the complexity of increasingly large-scale solutions. At the same time, however, organizations must respond to new business challenges with large-scale architectural initiatives that require some intentionality and planning. Intentional Architecture provides guidance and technical governance to agile programs and teams. These activities create the Architectural Runway needed to enable teams to deliver business value faster and more reliably. SAFe’s Principles of Agile Architecture illustrates how collaboration, emergent design, intentional architecture, design simplicity, designing for testability, prototyping, domain modeling and decentralized innovation support this important underpinning to Agile development.
#2 – Continuous Integration
Continuous Integration is the software practice of merging the code from each developer’s workspace into a single main branch of code, multiple times per day. In that way, all developers on a program are constantly working with the latest versions of the code, and errors and assumptions between developers — and between teams — are discovered immediately. This helps avoid the risk of deferred system level integration issues and its impact on system quality and program predictability. Continuous Integration requires specialty infrastructure and tools, including build servers and automated test frameworks, but even more important is the cultural mandate: individuals and teams get credit only for integrated and tested software.
In SAFe, teams perform local integration at least daily, but equally important is the responsibility to integrate the full system, and run regression tests as necessary, to assure that the system is evolving in the intended manner. Initially, that may not be feasible every day, so an initial, reasonable goal may be multiple times per sprint.
# 3 – Test-First
“Test-First” is a philosophy of approach that encourages the teams to reason deeply about system behavior prior to implementing the code. This increases the productivity of coding and improves fitness for use. It also creates a more comprehensive test strategy, whereby the understanding of system requirements is converted into a series of tests, typically prior to developing the code itself.
Test-first methods can be further divided into Test-Driven Development (TDD) and Acceptance-Test Driven Development (ATDD). Both are supported by Test Automation, which is required in support of Continuous Integration, team velocity, and development efficiency.
In Test-Driven Development, derived primarily from XP, developers write an automated unit test first, run the test to observe the failure, and then write the minimum code necessary to pass the test. Applicable primarily at the code method or unit (technical) level, this assures that a test actually exists and tends to prevent gold plating and feature creep of writing code that is more complex than necessary to meet the stated test case (requirement proxy).
Acceptance Test-Driven Development (ATDD) is an advanced discipline whereby the criteria for acceptable system behavior, as specific by the Product Owner, is converted to an automated acceptance test that can be run repeatedly to assure continued system conformance as the system evolves. ATDD helps keep the team focused on necessary system level – and customer observable – behavior, and gives the teams a clear success criteria target.
#4 – Refactoring.
Refactoring is a “disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior” [Ref 4]. As Agile eschews “Big Up Front Design” (BUFD), and “welcomes changing requirements, even late in development” [Ref 5], this implies that the current code base is either resilient or amenable to change as new business functionality is required. In order to maintain this resiliency, teams continuously refactor code in a series of small steps to provide a solid foundation for future development. Refactoring is a key enabler of emergent design and is a necessary and integral part of Agile. Neglecting refactoring in favor of “always new functionality” will quickly create a system that is rigid and non-maintainable, and eventually drives increasingly poor economic outcomes for the business.
In other words, refactoring is not optional, and you can learn more about SAFe’s perspective on refactoring here:
#5 – Pair Work
Pair Programming involves two programmers working at single workstation. One drives (types) while the other reviews, reflects, inspects and adds value to the coding process. Then the roles are switched. Pair programming is integral to XP, but as such it creates one of the more controversial aspects of XP, and it is perhaps one of the reasons that XP – and even more importantly, all its related, excellent software engineering practices – does not have as much momentum in the marketplace as some of us may have hoped.
We take a broader view of pairing in SAFe and prefer the label pair work, whereby team members work together in a variety of pairing aspects to peer review each others work, while providing for explicit and programmatic knowledge sharing. Pair work, and the communication and interaction required, is absolutely essential in achieving high quality of code. Pair work is also a great foundation for refactoring, CI, test automation and collective ownership.
In practice, we see a number of different styles of Pair Work in Agile teams, each has value on its own, and many can be used in combination. Some teams follow Pair Programming standards for all code development as prescribed by XP. Others pair developers and testers on a user story; each reviews the other’s work as a story moves to completion. Still others prefer more spontaneous pairing where developers pair for critical code segments, refactoring of legacy code, development of interface definition, and system-level integration challenges.
Simple put, two eyes are indeed far better than one, especially when it comes to building large, complex, and necessarily-highly reliable systems out of really small pieces!
#6 – Collective Ownership.
“Collective Ownership encourages everyone to contribute new ideas to all segments of the project. Any developer can change any line of code to add functionality, fix bugs, improve designs or refactor. No one person becomes a bottle neck for changes.”[Ref 6]. Collective ownership is particularly critical in SAFe, as big systems have really large code bases, and it’s unlikely that the original code developer is on the team or program. Even when that person is on the team, waiting for one individual to make a change is a handoff, and certain delay.
Implementing collective ownership at scale requires following proven, agreed-to coding standards across the program, embracing simplicity in design, applying intent-revealing code constructs and building interfaces that are resilient to changing system behaviors. Active and purposeful knowledge sharing by constant interaction within teams (pair work, individual rotation), and across teams (CI, Communities of Practice) is also part of the solution. Collective ownership also includes collective test ownership, as individuals working even in a narrow area of the code can break someone else’s tests, and one cannot wait for someone else to fix the test or underlying code. Strict standards for test code, tests written in natural language (tools like FIT, Cucumber, Robot Framework support this) and constant attention to health of the test suites are also critical.
In this article, we’ve described the benefits and effective practices of assuring endemic code quality while building big systems in a Lean and Agile manner. Code quality requires attention to detail and a commitment to technical excellence on the part of all individuals, teams and programs. It also requires active support of our Lean Thinking Manager-Teachers, who understand that critical business benefits cannot otherwise be achieved. But code quality is not just a set of software engineering practices, is also a culture of collaboration, visibility, frequent integration and validation of assumptions, and continuous refactoring to enable faster value delivery to the business.
 Leffingwell, Dean. Agile Software Requirements: Lean Requirements Practices for Teams, Programs, and the Enterprise, Addison-Wesley, 2011.
 Shalloway, Alan, et al. Essential Skills for the Agile Developer: A Guide to Better Programming and Design. Addison-Wesley, 2011.
 Beck, Kent, Cynthia Andres. Extreme Programming Explained: Embrace Change. Addison-Wesley, 2004.
 Fowler, Martin. Refactoring.com
Last update 2 May, 2013
© 2010-2013 Leffingwell, LLC. All rights reserved.