BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage Articles 9 Steps towards an Agile Architecture

9 Steps towards an Agile Architecture

Key Takeaways

  • A software product’s architecture is defined by the decisions and especially the trade-offs that the development team makes. Making these decisions and trade-offs transparent is essential to a successful software architecture.
  • Development teams have to experiment to prove (or disprove) their decisions; they can’t simply review their design to get the feedback they need to refine their decisions. For many teams, this is a very big change that takes time to master. 
  • Teams need to make these decisions and run architectural experiments continuously as they develop the system. Every time they add or change functionality they need to consider the architectural impacts of those changes. As a result, there is no "architecture phase" in the software development effort.
  • The organization has to be willing to accept the feedback they get from running experiments. They have to overcome their confirmation biases and be willing to reject "facts" that they "know" to be true when they obtain feedback that shows otherwise. 
  • Teams need help from each other to change. Sharing experiences, both good and bad, helps bring people together to learn from each other.
  • Don’t underestimate how hard it is to change the culture of an organization. To overcome this, start with developing single products and create support for and interest in working in a new way.
     

Introduction

In a series of previous articles, we have explained and explored the benefits of an agile architecture concept which we call the Minimum Viable Architecture (MVA) approach. The MVA approach is based on a simple set of ideas:

  • Architectures are defined not by a set of diagrams or documents, but by a set of critical decisions about how the system will meet its quality attribute requirements (QARs, or quality goals) and the trade-offs a team must make if they cannot fully satisfy the quality goals.
  • These decisions are continually reevaluated by the team as their understanding of the goals of the system and its quality attribute requirements increases, based on the experience they gain through experimentation.
  • It’s not possible to know whether the architecture of a system is fit for purpose without partially building and testing it.
  • The architecture of a system is built as part of a series of incremental product releases that test and validate the value of the system. We express this in terms of a set of minimal incremental releases (Minimum Viable Products) that test assertions about the value of the system.

Each of these points forces teams and their organization to significantly change the way they develop systems, from empowering teams to make decisions to accepting that the fitness of the architecture cannot be assessed without building something, to accommodating rework that results from feedback that the architecture needs to be improved.

These changes challenge many of the tacit assumptions that organizations make about how they should manage their work, and changing the mindsets behind these assumptions takes time. Just as an MVA approach does not create a system’s architecture in a single step, adopting an MVA approach takes a series of incremental steps as well.

Photo by Kurt Bittner - copyright belongs to the author

Start with a single development team

All change starts with one team who gets the idea that they could work differently and get better results. It’s important to start with just one team because you’ll need to prove that the approach works for at least one team before you try convincing all the teams in your organization that they need to work differently.

In this, the MVP/MVA approach has an analogue: you need to make small changes and get feedback on their effectiveness to make the right decisions on how to work. These small changes are often experienced in the following steps.

Step 1: Challenge limiting beliefs

Commonly and implicitly held beliefs can be the hardest barrier to overcome because they are never explicitly stated and therefore never challenged. These beliefs include:

  • The system can’t be delivered in a series of increments. If people believe that "everything" has to be included in the first release for the release to be valuable to someone, there won’t be any opportunity to deliver incrementally. The first step to overcoming this is to get everyone to agree that getting a subset of the system to a subset of the potential users of the finally finished product would be valuable.
  • Customer/user "requirement" must be completely understood before development starts. The problem with understanding customer/user needs is that customers/users don’t understand these needs themselves. Rather than asking users what they want in a solution, it’s better to ask them what they need to achieve and then design a solution that helps them achieve their desired outcome. Delivering the system to them incrementally and refining it based on their feedback lets them participate in defining the solution without burdening them with defining everything up-front.
  • The whole system must be developed before any of it can be tested. This belief often stems from management’s desire to reduce waste - "why test something you know isn’t finished?" Teams don’t have to fully embrace Test-Driven Development (TDD) to be continuously testing while they’re developing the system; it’s simply a good software engineering practice that goes hand-in-hand with writing modular code that separates concerns.
  • Customer needs and their related QARs are static and won’t change significantly. Customers don’t have to be consistent, and they can change their minds, sometimes because someone built what they asked for - once customers can see, touch, and use a part of the system, it may occur to them that there is a better way to solve the problem. Rather than resisting this effect, teams need to embrace it and use it to their advantage.
  • The architecture of a system can be devised purely based on a set of requirements, without any experimentation. Architectural decision-making inevitably involves a series of trade-offs, some of which can’t be understood without building and testing some code; architecting is not a purely intellectual exercise. As a result, organizations can’t develop an effective architecture without experimentation.
  • Architecture is reusable from one system to another so long as their domains are similar. Every software system is different, and different systems will require different decisions and trade-offs so long as the QARs of the systems are even a little different.

Step 2: Create acceptance of the MVP/MVA approach

The first step in breaking these limiting beliefs is to gain consensus that the system will be released in a series of increments. The essence of the Minimum Viable Product (MVP) approach is that each product increment will attempt to deliver at least one outcome to at least a subset of the users of the system. The organization will measure its success in achieving these outcomes and use that feedback to decide what it should work on next.

Using an MVP/MVA approach changes the conversations that a development team and its stakeholders have. Instead of simply focusing on "shipping something", everyone focuses on the outcome-oriented goals of the release and whether the product increment met those goals, and also whether the product increment can keep on delivering those outcomes over the expected lifetime of the product.

Step 3: Help the team learn to how develop an MVA

Learning to develop architecture incrementally takes practice, and no team is going to master it immediately. Most teams lean toward developing more architecture than they need, only to find that some of what they did was wrong, or at least unnecessary. They will probably struggle to balance trade-offs. They will also probably learn that some of the choices they made are wrong. All of this is good. They have to learn the right balance on their own, and they can only do this by making some wrong choices and seeing the impact.

You have to bear with them through this period. You can make suggestions, but even those may short-circuit their learning. The best thing you can do is help them retrospect on what they learned and help them to incorporate what they have learned into their next cycle.

Nearly all teams with whom we have worked struggle with the same things, at least early on. To help them through this, try to help them to:

  • Be willing to make trade-offs. Help the team to realize that it is impossible to design an architecture that would fully satisfy all of its QARs; most QARs are unknown, at least at first, and the ones that are known may be incorrect. Being willing and able to make thoughtful trade-offs is the essential architecting skill.
  • Make the trade-offs transparent. Document them, and bring them into the open where they can be discussed and debated. Most importantly, measure the actual results of the decision and review whether the decision achieved its desired result.
  • Make architecture executable, not just documents and diagrams. While inspections can spot some kinds of errors, there is nothing like executing code to make feedback concrete. Most systems are complex, which means that the interaction of components, often developed by different teams if not different organizations, is not deterministic. Strange things will happen that "should not happen" but do. The only way to know for certain is to create an executable product you can empirically evaluate.
  • Avoid creating too much architecture before obtaining feedback. If there is an MVA mantra, it is to never delay feedback. Ever. Get really good at creating and evaluating the smallest increment possible to answer the question "Is our latest decision a good one?"

Step 4: Establish feedback loops to improve the architecture

It is obvious to see how feedback helps a team to improve their MVP, but they can also use the same mechanism to evolve their MVA; each MVP/MVA is an opportunity to gather feedback on the ability of the system to meet its QARs. Just as the purpose of the MVP is to help a team avoid investing in product capabilities that have no value, the purpose of the MVA is to balance the is to avoid over-investing in architecture when it isn’t necessary or useful.

Some QARs are not known, and even not knowable, until the team builds and releases a system; they cannot predict how popular the product will be, or the technical challenges they will have to overcome to meet unexpected demand. From a business perspective, wildly successful products are a good thing, but for the development team, they are risky. Feedback helps them to manage this risk with better information.

Step 5: Make decisions intentionally and continuously

Once a team can deliver in short cycles and gather feedback, it needs to use that ability to make conscious decisions about each incremental MVP and MVA:

  • For the MVP, it needs to form hypotheses about what capabilities it believes are most valuable, and it needs to decide how it will know if these "guesses" are correct.
  • For the MVA, it needs to decide what it will build so that if the MVP is successful the team will be able to sustain the value over time.

This last point is where the hard decisions come. The team is faced with several potential outcomes:

  • The MVP might not be as valuable as the team hopes, or it might not be valuable at all. In this case, the team does not want to develop a lot of supporting capabilities that aren’t useful. This might lead them to wait and see if the MVP is useful before they develop architecture to support it. Lagging the development of the MVA behind the MVP might make sense, except that:
  • The MVP might be valuable, and even wildly so, causing adoption to skyrocket and then plummet because the system is not architected to support the successful adoption by its customer base. If the MVA is not adaptable quickly, it may cause the MVP to fail.

Balancing these two possible alternatives means that the MVA must be good enough for the current needs of the MVP while being quickly adaptable if those needs change. One way to think about the MVA is that each one is, in a sense, an option on the future capabilities of the product.

Having discussions about trade-offs and their possible benefits and limitations is really the essence of the architectural work the team does.

Step 6: Adapt to feedback

Feedback is what helps a development team prove and improve their product’s architecture. Teams who think merely delivering product Increments without measuring whether they achieve their desired results are missing an important opportunity to understand whether they are delivering value and, if they are falling short of their goals, how to improve. This is easy to understand for the functional parts of the product, the MVP, but it is just as true for the architecture, the MVA.

Gathering feedback means the development team will have to create tests and find ways to measure the performance of the product Increment against architectural goals. They have to build time for this work into their plans for the increment. This is more challenging than it sounds - stakeholders tend to push hard to add more things to the MVP so the team must effectively push back to invest in the MVA, including creating the means to validate their architectural decisions.

From an architectural perspective, evaluating the performance, scalability, security, and reliability of the system, among other qualities, provides the team with valuable feedback that helps them decide what they should do next - do they continue along the same path, or do they need to change course? Without empirical data, their decisions are informed only by opinions. Having data can help them make more effective trade-offs.

As you add more teams, build a foundation for broader success

Once you have proved to yourself (and your doubters) that the MVA approach works for you, you can expand the number of teams using the approach. As you do, use what you learned with the first team to help the new teams. Also, connect the teams so they can learn from each other. Finally, start dealing with the organizational constraints and barriers to the approach in a systematic way.

Step 7: Foster a community focused on agile architecting

Once you have one team working in the new way, you will have proof that the new approach works. It’s important to establish this proof to justify broader change, and it’s fairly easy to change one team without changing the whole organization because it’s easy to "bend the existing rules" without having to wholly replace them.

Each team, more or less, follows the path we’ve laid out above. There aren’t any shortcuts to experiential learning, however; just as you can’t learn how to develop software simply by listening to someone talk about how they do it, teams have to develop their decision-making skills. They can learn things they should look out for from other teams, and that’s where a community is helpful. The focus of this community varies between organizations, but often includes:

  • Sharing experiences and learning from each other. The most important things to share are not "the answers" but the thought processes that led to the answers. Learning the questions to ask and the trade-offs to consider is more important than the actual decisions themselves. Every team has to decide for itself, but knowing how others look at the problem often triggers interesting discussions.
  • Sharing common components and frameworks. Even though they cannot share complete architectures, teams facing similar problems will often need similar components or building blocks. Having a place to share these, and agreements on who can update and how can help everyone.
  • Contributing to common development and testing infrastructure. Just as with components, different teams often have similar, though not identical, needs for automated build and testing tools. While some organizations have this owned by an infrastructure team, communities of practice can also play a role in identifying new tools and approaches that other teams can use.
  • Helping to grow an empirical engineering culture that values experiential learning. Even when there isn’t a consensus on a solution, just knowing what other teams have experienced can help development teams better understand their options and alternatives.
  • Helping teams adopt MVA practices. Providing coaches/mentors, and training if the teams need that level of help, helps teams to grow their MVA capabilities.
  • Growing management support, especially for embracing transparency. Many managers with whom we have worked describe themselves as not liking surprises. Feedback is sometimes unforgiving. Communities can provide ways to share experiences overcoming management discomfort at dealing with the unknown and unknowable.

Step 8: Empower teams to make their own trade-offs while owning the long-term consequences

Empowering teams to make their own decisions about trade-offs based on feedback from their experiments is essential, but it can also be threatening to the status quo. Consider what happens when:

  • A team decides not to use an internal "standard" framework that some other department just licensed for millions of dollars, but which cannot meet the team’s QARs.
  • A team decides that the security framework being touted by some other product team does not meet their needs.
  • The infrastructure department won’t approve a team’s request for access to a mainframe testing environment that the team feels they need to verify their architecture can meet scalability and throughput QARs. The infrastructure department says that review meetings will be sufficient and asks the team to thoroughly document their QARs.

We could go on, but you get the idea. Empowering teams sometimes means that they are going to come to a different conclusion than the "experts" in some other part of the organization. This can become a problem if the "experts" feel their expertise is being questioned rather than accepting that their decisions might not work in all situations. Leaders in the organization need to make it okay for different teams to arrive at different decisions so long as their evidence and reasoning is sound.

Some will compellingly (and sometimes forcefully) argue that "standards" are important and that the organization cannot support lots of different technologies, and we agree with that, to a point. The long-term supportability consequences of technical decisions is the primary concern of architectural decisions, and the development team will have to make a case that better satisfaction of QARs is worth the trade-off in complexity of taking on an additional technology. Being constrained by "standards" decisions made by another team does not help teams make better decisions, it merely limits their alternatives.

Step 9: Evolve the culture by dealing with the "elephants in the room"

Photo by Kurt Bittner - copyright belongs to the author

You successfully went through the first eight steps. Unfortunately, you still have to confront the biggest obstacle: evolving the organization’s culture. In reality, this "step" is not a step but a background activity that you have to run in parallel with all the steps we’ve described so far.

An organization’s culture consists of a set of largely tacit agreements about how things are supposed to work in the organization. Culture is, by its very nature, a barrier to change. Culture is a positive force when you want to keep small disruptions from upsetting the working of the organization, but when a new "improvement" threatens the status quo, culture acts like an immune system that destroys new ways of working like an invading infection. The problem with changing culture is that it evolves spontaneously and naturally as people work together so that explicitly changing it is almost impossible.

There are several "elephants in the room" that teams adopting an MVA approach need to deal with if they are to be successful, and that are embedded in the culture of most organizations;

  • People resist change, especially if the change is not their idea. For most people, change means loss of control and uncertainty; they don’t like it. Involving them in the change, letting them decide what changes and when can help them feel more comfortable with it.
  • The "blame game" is destructive and counter-productive. People are afraid of getting blamed if the change doesn’t work. Since architectural decisions are always uncertain, frame them as experiments that need to be tried. If they don’t produce the anticipated result, adapt and move on. Knowing that something won’t work is just as valuable as knowing that something will work.
  • Transparency can make people uncomfortable. No one likes having their ideas criticized, but when dealing with the unknown everyone is going to have ideas that don’t work. Decoupling ideas from the people who suggest them and looking at all feedback as good is one way to help people become more comfortable with transparency.
  • Empowering teams changes the status dynamics. Top-down managers who are used to telling people what to, and getting recognition when the right path is followed, struggle with letting teams make their own decisions. "What if they make a bad decision? It will reflect poorly on me." Viewing decisions as experiments that need to be tested, and then using frequent feedback to improve removes a lot of the risk from decision-making. And re-orienting the management culture to focus on growing teams instead of being the "hero decision-maker" also helps.
  • Perceptions about regulatory compliance lead people to believe that they can’t deliver the system in increments. In some industries, regulators must approve product changes, and they may not be willing or able to work in small increments. However, not all changes affect the regulated aspects of the product; many affect the usability or user experience without changing the underlying product. Being clear about what changes regulators must approve and then involving them earlier helps.

Conclusion

Change starts, in our experience, with one team, and it grows team by team; we’ve never seen so-called "enterprise transformations" work any other way.

Each of these teams needs to be working on a problem that can only be solved empirically, through experimentation; if the problem is well-understood enough for "best practices" and copy-paste solutions to work, the teams don’t need agility/empiricism.

The first thing these teams will need to do is to learn how to deliver incrementally. This usually requires helping stakeholders to understand what incremental delivery means to them, and how the development team will evolve the product through a series of releases.

While developing and delivering incrementally, development teams will shift their architectural focus onto decisions and away from documents and diagrams.

As the organization builds experience and success, you can expand the approach to more teams. While you do this, you’ll need to build a community to share experiences and artifacts and to help the teams understand how to make architectural decisions and trade-offs.

As you shift decision-making to teams, you will also upset the status quo; don’t underestimate how disruptive this can be. Deal with organizational issues continuously, and anticipate the conflicts that shifting status relationships can create.

About the Authors

Rate this Article

Adoption
Style

BT