More on this book
Community
Kindle Notes & Highlights
Read between
April 4, 2020 - March 8, 2021
Conway’s law tells us that we need to understand what software architecture is needed before we organize our teams, otherwise the communication paths and incentives in the organization will end up dictating the software architecture. As Michael Nygard says: “Team assignments are the first draft of the architecture.”7
Loose coupling—components do not hold strong dependencies on other components High cohesion—components have clearly bounded responsibilities, and their internal elements are strongly related Clear and appropriate version compatibility Clear and appropriate cross-team testing
Don Reinertsen, author of The Principles of Product Development Flow, says “we can also exploit architecture as an enabler of rapid changes. We do this by partitioning our architecture to gracefully absorb change.”10 Architecture thus becomes an enabler, not a hindrance, but only if we take a team-first approach informed by Conway’s law.
“if we have managers deciding . . . which services will be built, by which teams, we implicitly have managers deciding on the system architecture.”11
Organization design and software design are, in practice, two sides of the same coin, and both need to be undertaken by the same informed group of people. Allan Kelly’s view of a software architect’s role expands further on this idea: More than ever I believe that someone who claims to be an Architect needs both technical and social skills, they need to understand people and work within the social framework. They also need a remit that is broader than pure technology—they need to have a say in organizational structures and personnel issues, i.e. they need to be a manager too.12
“managers should focus their efforts on understanding the causes of unaddressed design interfaces . . . and unpredicted team interactions . . . across modular systems.”14
Team of Teams, retired US Army General Stanley McChrystal notes that the best-performing teams “accomplish remarkable feats not simply because of the individual qualifications of their members but because those members coalesce into a single organism.”
Use Small, Long-Lived Teams as the Standard
If trust is missing or reduced due to a larger group of people, speed and safety of delivery will suffer.
Around five people—limit of people with whom we can hold close personal relationships and working memory Around fifteen people—limit of people with whom we can experience deep trust Around fifty people—limit of people with whom we can have mutual trust Around 150 people—limit of people whose capabilities we can remember
A single team: around five to eight people (based on industry experience) In high-trust organizations: no more than fifteen people Families (“tribes”): groupings of teams of no more than fifty people In high-trust organizations: groupings of no more than 150 people Divisions/streams/profit & loss (P&L) lines: groupings of no more than 150 or 500 people
Every part of the software system needs to be owned by exactly one team. This means there should be no shared ownership of components, libraries, or code.
team ownership of code should not be a territorial thing. The team takes responsibility for the code and cares for it, but individual team members should not feel like the code is theirs to the exclusion of others. Instead, teams should view themselves as stewards or caretakers as opposed to private owners. Think of code as gardening, not policing.
Good Boundaries Minimize Cognitive Load
With a team-first approach, the team’s responsibilities are matched to the cognitive load that the team can handle.
Intrinsic cognitive load—relates to aspects of the task fundamental to the problem space (e.g., “What is the structure of a Java class?” “How do I create a new method?”) Extraneous cognitive load—relates to the environment in which the task is being done (e.g., “How do I deploy this component again?” “How do I configure this service?”) Germane cognitive load—relates to aspects of the task that need special attention for learning or high performance (e.g., “How should this service interact with the ABC service?”)
for effective delivery and operations of modern software systems, organizations should attempt to minimize intrinsic cognitive load (through training, good choice of technologies, hiring, pair programming, etc.) and eliminate extraneous cognitive load altogether (boring or superfluous tasks or commands that add little value to retain in the working memory and can often be automated away), leaving more space for germane cognitive load (which is where the “value add” thinking lies).
If we stress the team by giving it responsibility for part of the system that is beyond its cognitive load capacity, it ceases to act like a high-performing unit and starts to behave like a loosely associated group of individuals, each trying to accomplish their individual tasks without the space to consider if those are in the team’s best interest.
A simple and quick way to assess cognitive load is to ask the team, in a non-judgmental way: “Do you feel like you’re effective and able to respond in a timely fashion to the work you are asked to do?”
When measuring cognitive load, what we really care about is the domain complexity—how complex is the problem that we’re trying to solve with software?
Match Software Boundary Size to Team Cognitive Load To keep software delivery teams effective and able to own and evolve parts of the software systems, we need to take a team-first approach to the size of software subsystems and the placement of boundaries. Instead of designing a system in the abstract, we need to design the system and its software boundaries to fit the available cognitive load within delivery teams. Instead of choosing between a monolithic architecture or a microservices architecture, design the software to fit the maximum team cognitive load. Only then can we hope to achieve
...more
Increase the quality of developer experience (DevEx) for other teams using your team’s code and APIs through good documentation, consistency, good UX, and other DevEx practices.
Generally speaking, each stream-aligned team will require a set of capabilities in order to progress work from its initial (requirements) exploration stages to production. These capabilities include (but are not restricted to): Application security Commercial and operational viability analysis Design and architecture Development and coding Infrastructure and operability Metrics and monitoring Product management and ownership Testing and quality assurance User experience (UX)
Adam liked this
It’s critical not to assume each capability maps to an individual role in the team; that would mean teams would have to include at least nine members to match the list above. Instead, we’re talking about being able, as a team, to understand and act upon the above capabilities. This might mean having a mix of generalists and a few specialists. Having only specialized roles would lead to a bottleneck every time a piece of work depended on a specialist who might be currently busy.
Adam liked this
An enabling team is composed of specialists in a given technical (or product) domain, and they help bridge this capability gap. Such teams cross-cut to the stream-aligned teams and have the required bandwidth to research, try out options, and make informed suggestions on adequate tooling, practices, frameworks, and any of the ecosystem choices around the application stack.
team interactions rather than individuals. The end goal of an enabling team is to increase the autonomy of stream-aligned teams by growing their capabilities with a focus on their problems first, not the solutions per se. If an enabling team does its job well, the team that it is helping should no longer need the help from the enabling team after a few weeks or months; there should not be a permanent dependency on an enabling team.
Dave Bouwman and 1 other person liked this
Our high-level goal is to enable teams to deliver features faster and with higher quality. We have an initial eight weeks to improve the following metrics: Time taken per successful deployment Absolute number of successful deployments per day Time taken to fix a failing deployment Time from code commit to deployment (cycle time)
The primary purpose of an enabling team is to help stream-aligned teams deliver working software in a sustainable, responsible way.
The platform team provides internal services to reduce the cognitive load that would be required from stream-aligned teams to develop these underlying services.
platform team uses strong collaboration with stream-aligned teams to understand their needs.
Generally speaking, teams composed only of people with a single functional expertise should be avoided if we want to deliver software rapidly and safely.
Organizations that optimize for a safe and rapid flow of change tend to use mixed-discipline or cross-functional teams aligned to the flow of change—what we call stream-aligned teams.
This drive to “simplify the developer’s life” (as Conway puts it)20 and reduce cognitive load (see Chapter 3) is an essential aspect of a good platform.
As Kenichi Shibata of global publishing company Conde Nast International says, “The most important part of the platform is that it is built for developers.”21
To avoid the too-common trap of building a platform disconnected from the needs of teams, it is essential to ensure that the platform teams have a focus on user experience (UX) and particularly developer experience (DevEx). This means that as the platform increases in size, expect to add UX capabilities to the platform teams.
If the underlying or lower-level platform is not well defined or stable, the upper platform will itself be unstable, and unable to provide the firm foundation needed to accelerate software delivery within the rest of the organization. If the underlying platform has operational quirks or performance problems, the platform team group will need to build insulation abstractions and workarounds for the operational problems, and/or advertise the potential problems to Dev teams and make it easy for them to avoid hitting the problems.
multi-layer viable-systems model (VSM) described by Stafford Beer in the classic book Brain of the Firm.23
Move to Mostly Stream-Aligned Teams for Longevity and Flexibility Most teams in a flow-optimized organization should be long-lived, multi-disciplined, stream-aligned teams. These teams take ownership of discrete slices of functionality or certain user outcomes, building strong and lasting relationships with business representatives and other delivery teams. Stream-aligned teams can expect to have cognitive load matched to their capabilities through the support and help they get from enabling teams, platform teams, and complicated-subsystem teams.
Adam liked this
Tooling Teams to Enabling Teams or Part of the Platform A tooling team can easily turn into a siloed tool maintenance team over time if the initial mandate for the team is not specific enough or not time bounded. Besides the emotional attachment to the toolchain, team members’ technical skills can become outdated and their effort wasted in minor improvements led by inertia rather than by real needs. Tooling teams are typically better run either as enabling teams—with a short-lived and highly focused remit—or as part of the platform (with a clear, well-informed roadmap).
Adam liked this
The most effective pattern for an architecture team is as a part-time enabling team (if one is needed at all). The team being part-time is important: it emphasizes that many decisions should be taken by implementing teams rather than left to the architecture team. Some organizations compose a virtual team from members of other teams. This virtual team meets regularly to discuss and evolve the architecture aspects of the systems. This is akin to the chapter or guild terminology used by Spotify (see Chapter 4).
the architecture team should support the other teams, helping them to be as effective as possible, rather than imposing designs or technology choices on other teams. As Forsgren, Humble, and Kim put it in Accelerate, “Architects should collaborate closely with their users—the engineers who build and operate the systems through which the organization achieves its mission—to help them achieve better outcomes and provide them the tools and technologies that will enable these outcomes.”26
The litmus test for the applicability of a fracture plane: Does the resulting architecture support more autonomous teams (less dependent teams) with reduced cognitive load (less disparate responsibilities)?
Our product teams are typically made up of four developers, one production manager, one QA, and one UX/UI designer.
you have microservices but you wait and do end-to-end testing of a combination of them before a release, what you have is a distributed monolith.”10
Intermittent collaboration gives the best results. Researchers recently devised an ingenious experiment to assess the effectiveness of team-based solutions to complex problems. Bernstein and colleagues found that “groups whose members interacted only intermittently . . . had an average quality of solution that was nearly identical to those groups that interacted constantly, yet they preserved enough variation to find some of the best solutions too.”1 Intermittent collaboration found better solutions than constant interaction.
Adam liked this
Collaboration: working closely together with another team X-as-a-Service: consuming or providing something with minimal collaboration Facilitating: helping (or being helped by) another team to clear impediments A combination of all three team interaction modes is likely needed for most medium-sized and large enterprises (and these modes are useful to introduce at smaller organizations sooner than many people expect). In addition, one team might use two different interaction modes for two different teams with which it works.
Adam liked this