Innovation comes from the producer, not the customer.
—W. Edwards Deming
Features and Components include two key abstractions we use to build software and systems:
Features are those behaviors of the system that directly fulfill some user need.
Components are distinguishable system parts that provide and encapsulate common functions needed to implement features.
The Agile model’s value delivery focus emphasizes features (and constituent stories) that solve user needs and differentiate solutions. However, resilient large-scale systems are built out of components that provide for separation of concerns, foster logic reuse, and improve testability. These properties provide a foundation for fast system evolution.
Both abstractions exist and may be commonly recognized in an Enterprise. Particularly in the context of enterprise agility, some interesting discussions can arise about how to organize teams—around features, around components, or around some mix of the two. Getting the organization of the enterprise right drives innovation on scalable systems that can grow as your knowledge grows. Getting it wrong leads to one of two suboptimal outcomes:
Brittle systems that are unmaintainable and rapidly obsolescent (all features, all the time)
Brilliantly designed systems with inherent future user value to keep the enterprise competitive (all components, all the time)
This chapter describes features and components in the context of large-scale Agile systems development and provides some organizational guidance to continually evolve the Agile organization to optimize velocity and accelerate value delivery.
The architecture of a software system can be described, in part, in terms of its component structure and its features. The components interact to deliver the consistent user-facing behaviors that constitute the features. Teams build systems out of components to provide scalability, flexibility, common functions reuse, and maintainability.
The creation of a specific component can be driven by a number of motivations:
Implementation/isolation of a specific technology (e.g., PHP-based user interface, Java-based business logic)
Reuse of logic (e.g., transaction processing module)
Protective isolation for purposes of controlling security, compliance, safety, and so on
Support for an anticipated high rate of changing requirements (e.g., bridge/adapter modules, proxy objects)
The word ‘component’ is a pretty broad term. In SAFe, it can refer to any of the following:
A system layer (such as the UI, Application, or Data layer)
A software module or package
An application library
A subsystem
A component team is a Define–Build–Test Team whose primary area of concern is restricted to a specific component, or a set of components, of the system. Accordingly, the team backlog typically consists of Technical Stories (as opposed to User Stories), as well as Refactors and Spikes. It can make sense to create a component team when a component has the following characteristics:
Can be used by other entities, business units, or subsystems
Would otherwise appear in many places in the code base, complicating maintenance and testability
Can be uniquely responsible for functionality related to compliance, safety, security, or regulation
Contains unique or legacy technology
Provides algorithms or logic that require specific, deep technical and/or theoretical expertise
Operates on large data sets, performs highly intensive computations, or has to satisfy some critical nonfunctional requirements, such as availability or throughput
Prior to the Agile development movement, most large-scale systems development programs were typically organized around components and subsystems (the old mantra: Organization follows architecture). Therefore in an Agile transformation, sometimes the simplest first step is to create Agile Teams that follow the existing, component-based organizational pattern (Figure 1).
The disadvantages of the previously described model are obvious: Most new features create dependencies that require cooperation between these teams. This is a continuing drag on velocity, as the teams spend much of their time discussing dependencies between teams and testing behavior across components rather than being able to deliver end-user value. We certainly don’t need components or component teams in the following situations:
Most new user stories require unique changes to specific parts of the code base.
The code of interest has no higher criticality than any other component in the system.
The code does not require unique, rare, or different skills and technologies.
The code will be not heavily used by other code, components, or systems.
In these cases, it is best to create feature teams that are organized around user-centered functionality. Each team, or small team of teams, is capable of delivering end-to-end user value (Figure 2). Feature teams operate primarily with user stories, refactors, and spikes. In addition, technical stories may occasionally occur in their backlog.
Even then, though they are called feature teams, it is not always true that such a team can complete a feature by itself. Features can be too big to be consumed by one Agile team and so may be split up into multiple user stories. These, in turn, are implemented by other feature teams. In addition, the very notion of a feature or component team is a bit simplistic, as many effective teams have responsibility for a number of both features and components. Nevertheless, the following guideline applies:
To ensure the highest feature throughput, SAFe generally recommends a mix of perhaps 75 to 80 percent feature teams and 20 to 25 percent component teams.
Given that a mix is most likely to be appropriate, two main factors drive it:
The practical limitation of the degree of specialization required
The economics of potential reuse
Figure 3 illustrates these parameters and a curve that can be used to choose one organization over other options.
This ‘mixed model’ emphasizes additional capabilities needed to drive program velocity:
System-level, Continuous Integration (CI) infrastructure – Feature teams must be able to integrate the entire system at any desirable point.
Test automation – Broad, automated regression test suites must be built and available.
The System Team – This special team is engaged in actively improving and supporting the CI systems and processes used by the feature and component teams.
Communities of Practice – These communities can be organized to share component-related knowledge across feature teams.
Strong emphasis on endemic code quality – Along with refactoring skills, this perspective is mandatory for scaling.
This chapter described the issues of organizing Agile programs around feature teams versus component teams. Evolution to a mix of these teams, although one biased toward feature teams, appears to produce the highest velocity and efficacy of larger-scale Agile development. In general, dependencies are fewer and easier to manage, and value throughout is higher with feature teams. Even then, however, we recognize that features and components are both abstractions, such that one person’s feature may be another’s component. To that end, Agile programs must continually inspect and adapt, and indeed reorganize, as necessary to follow the value that is driving the market.
LEARN MORE
[1] Leffingwell, Dean. Agile Software Requirements: Lean Requirements Practices for Teams, Programs, and the Enterprise. Addison-Wesley, 2011.