Evolutionary Architecture And Systems Thinking
Checking session availability…
Hang tight while we load the latest updates.
In this talk, Rebecca Parsons, CTO of ThoughtWorks, will share how good architecture principles and forcing functions enable more empowered developers and more iterative solutions.
Rebecca will touch on:
- What defines good architecture principles?
- How does design aligns with evolutionary architecture, and
- Examples of iterative solutions
Evolutionary Architecture And Systems Thinking
Rebecca Parsons at UXDX Europe. Video: https://www.youtube.com/watch?v=sCPSCJUUfbk
Readable transcript: edited from the recording's captions for readability (fillers and false starts removed, punctuation and section headings added). Wording is the speaker's own. Timestamps are positions in the video. Names marked [?] could not be verified against the audio.
Systems thinking and design thinking
[00:00:00] My name is Rebecca Parsons. I am the Chief Technology Officer for ThoughtWorks, and I want to talk to you today about the intersection of design thinking, systems thinking and evolutionary architecture. Our slides are going to advance. There we go. Specifically, each one of those two disciplines, design thinking and systems thinking, influences what we talk about when we talk about the architecture of systems, and I want to do a bit of a dive into each of these concepts. Of course, any one of these concepts could be a workshop in and of itself, so I'm just going to highlight a couple of aspects of design thinking and systems thinking and try to develop those ideas in the context of evolutionary architecture.
[00:00:51] First, let's start with defining our terms. In very simple ways, systems thinking requires us to look at not just the individual elements of the system, but also the way those elements connect with each other and interact, and finally the function or purpose of that system. All three of those components are an important part of thinking about a system. If, when you think about a system, you only look at the elements or you only look at the connections, you're missing something fundamental about what the system is about and what it's trying to tell you.
[00:01:33] Most of the audience probably knows a whole lot more about design thinking than I do, but there are a couple of important aspects from design thinking that really influenced what we're talking about with evolutionary architecture. The first is the focus on the user, on the human and what outcomes that person is trying to achieve, focusing really on that human perspective as opposed to just thinking about what's technologically feasible. What we're really trying to do here is focus on the outcome, not the implementation. Very often as technologists, we get all wrapped up in what we're actually going to build and forget that there's a purpose out there. There's an outcome that we're trying to achieve.
[00:02:33] We want to use design thinking and the process of design thinking to help us keep our users at the center of what we're building. In the case of architecture, there are all kinds of different humans that are our customers. They might be the actual end customer. They might be an internal person, maybe a customer support call center person. They might actually be a developer. One of the things that has really started to take hold when we look at architecture is talking about the developer experience. How is it that the architecture either enables or impedes the experience of the developer to be able to actually deliver something to the ultimate customer? So design thinking has a lot to offer when we think about the overall process of building an evolutionary architecture.
What evolutionary architecture means
[00:03:34] Then what is an evolutionary architecture? An evolutionary architecture supports guided incremental change across multiple architectural dimensions. I want to talk about several of these words, but I want to start with why we call it evolutionary architecture. One of my colleagues, Neal Ford, and I have been talking about evolutionary architecture for quite some time. When I first heard him talk about it, he was actually calling this emergent architecture. He and I had a very robust conversation about why I thought that was a terrible name, because when you think of emergence, it's just whatever happens: "Oh, well, it's just sort of happening now."
[00:04:28] Whereas when I think about something that's evolutionary, and I'm thinking about this from the context of evolutionary computation, you have some kind of objective, you have something that constitutes good. And it's important to realize that there is no such thing as one good architecture. For some systems, security and privacy are paramount. For others, it's responsiveness. For others, it's scale. You can't get all of those things at once. So we need to think about how we are going to balance these different parts of our architecture.
[00:05:20] That's where the "guided" comes in. We have a notion of fitness functions, which tell us, for this particular system, for my particular organization, what constitutes good. Maybe it's overall performance, maybe it's resilience, who knows. But we need to make a determination that says, this is how I'm going to prioritize these different architectural characteristics.
[00:05:51] The second important phrase in this definition is incremental change. It used to be that people would literally put their architectural roadmap up on the wall for five years and ten years. That's simply not possible anymore. It's not feasible to speculate that far out, so we need to be able to introduce the notion of incremental change into architecture. When I first started talking about evolutionary architecture, people would come up and say, "Don't you think you're being professionally irresponsible to talk about changing architecture? That's the bedrock, that's the entire foundation of all of our systems."
[00:06:38] But we can't any longer say, "I know that this architecture is going to be right for the next ten years," because the pace of change is simply too great. We have to enable some kind of dynamic equilibrium where we're balancing the changing expectations of our customers, the changing regulatory environment and the changing technology landscape.
[00:07:06] The third is this notion of "across multiple dimensions". What we recognize here, as I was saying about the guided aspect, is that different architectural characteristics carry different weight in different systems. So we want to think about how we are going to balance the tension between our different architectural characteristics. That's evolutionary architecture.
[00:07:33] One of the important things about architecture, and this is paraphrasing a quote from Gregor Hohpe, who wrote the Enterprise Integration Patterns books, is that you don't have an architecture diagram if it only has boxes. It isn't just the different components or systems or microservices, or whatever you want to call the individual pieces of your architecture. Those are interesting and important, but you don't really understand how the system works unless you know how those different components interact with each other. How does information flow through? How does behavior flow from one part of the system to another to achieve the objectives we are trying to achieve with our system?
[00:08:31] Hopefully you can now start to see there's a really close tie between systems thinking and architecture. We can't really understand what our architecture is trying to achieve unless we focus both on the elements and the interconnections, and then the overall function or purpose of an architecture is to deliver to whatever the end customer is the value, the outcomes, that they are seeking.
Principles: feedback and maintainability
[00:09:04] Now I want to talk about a few basic architectural principles that help us more successfully deliver on evolutionary architecture. The first one is feedback. Whether you're thinking about feedback loops from systems thinking, or about the more iterative, experimental learning cycles of design thinking, feedback is essential. In fact, one of the nice things about the Agile revolution, if you will, is this focus on how I know things are working, and building in those fast feedback loops at all levels of the system, for us to be able to understand: are we achieving what we want to achieve? Are we delivering the value that we want to deliver?
[00:10:02] What this allows us to do is start to enable this kind of test-and-learn cycle, where I'm going to put forward a testable hypothesis of how I might achieve more value for my customer, then deliver some code, and then actually test that hypothesis. I've been in this business for a long time, and if you just summed up all of the money that all of these systems were supposedly going to save for all of these different organizations, you'd have an incredible pile of money. But very often in the past, we never actually went back and said, "OK, did this actually achieve the value that I expected it to?" Because the deliveries were so large, and because the feedback cycles were so slow and weak, we couldn't actually determine whether we did what we set out to do.
[00:10:57] The second fundamental principle I want to talk about is maintainability. Too often when we talk about software development, we focus on developer productivity in writing the code the first time. But we spend a whole lot more time over the life of a particular piece of code trying to read it and trying to understand it than we ever do trying to write it in the first place. What we want to do instead is focus on how maintainable the code is, how readable the code is, and this leads us down the path of truly thinking about internal software quality.
[00:11:47] People often say, "OK, I have to trade off cost for quality." But that's not true with software. Sure, you can get a short-term productivity boost if you don't think too much about software quality, but you will quickly lose that advantage as your code becomes harder to understand and harder to maintain. So to have a system that can respond to the kind of changes we're talking about, we need to have a focus on the maintainability and the evolvability of both our code and the overall architecture.
Principles: coupling, boundaries and continuous delivery
[00:12:29] The third piece is to really think about the combined notions of the coupling between these components, microservices, whatever you want to call them, and how I draw the boundaries. In the past, we've often used system boundaries as the way we think about our architecture. But if you think about it from the perspective of the business and the users, they don't really care whether their functionality is implemented in one box or five. They only care about getting the behavior that they want.
[00:13:16] One of the things we can do to improve the evolvability of the overall system is to look at those individual component parts and try to conceptualize: what is the business objective of this? What is the business concept that is being manifested here, or the business behavior that is being expressed? Because if those boundaries are around things that come naturally in the business, they're a whole lot easier to rearrange to achieve new business outcomes, because they're aligned with the concepts that the business is talking about.
[00:13:55] One of the major advances in our ways of thinking about this comes from the book Domain-Driven Design, where they talk about bounded contexts as well as the ubiquitous language. We as technologists need to bring that business context into our vocabulary so that we can have a shared understanding of what, again, the system is trying to achieve for the overall end user.
[00:14:33] How do we make this work? I want to go back to a comment I made previously: "Don't you think you're being professionally irresponsible?" One of the important enablers for evolutionary architecture has been the introduction of the notion of continuous delivery. What continuous delivery does is set up the expectation that you always have code that is ready to go into production. In order to do that, you have to have a tremendous amount of automation, particularly around testing, but also around the provisioning and deployment of your code.
[00:15:16] I very often get asked, "Well, I don't want something to go directly into production because some random developer somewhere checked in a line of code." The important part of continuous delivery isn't that code does flow automatically without any human intervention. It's that it can. And the important part of this to me, within the context of evolutionary architecture and design thinking, is that this allows experimentation.
[00:15:50] It used to be, because deployments were so risky, that we only did them twice a year, or maybe once a quarter. Everybody came in at three o'clock on a Sunday morning and just hoped that things didn't go wrong this time. Any celebrations after a deployment were not about the new features, but about the fact that you didn't get a call from the CEO, yelling and screaming at you because something went so horribly wrong with the deployment. You're not going to do a whole lot of experiments if there's a lot of risk attached to doing that experiment, and that was the situation we used to have.
[00:16:33] For me, what continuous delivery has enabled is this ability to be confident that when you release something, it's actually going to go smoothly. And if it doesn't, you're going to know very quickly, you're going to be able to roll it back, and the consequences will be minimal. Once you have that confidence, then you can start to experiment. You can start to allow little experiments to happen in different parts of your organization to see what might stick, rather than having to place one big bet. We can place 20 small bets, and one of those is really going to pay off for us. But it probably would be professionally irresponsible to try to do some of these things if you didn't have the rigor that is required to truly get to continuous delivery.
Design thinking in evolutionary architecture
[00:17:34] Now I want to talk about each of these aspects, design thinking and systems thinking, in the context of evolutionary architecture. Let's start with design. This whole design thinking process is trying to enable creativity. You want to gather inspiration for what might be possible. You want to quickly make that idea tangible so that you can test it and see: does this in fact improve my developer experience or my user experience? Is this product really of value to my end customer? And build in that test-and-learn cycle. I'm going to throw a hypothesis out. "Oh, that didn't turn out quite how I expected. Maybe I should look over here for something like that."
[00:18:26] What we're trying to do here is allow the systems to be incredibly responsive to increased opportunities coming from our users, or to respond to competitive threats. The expectations that our users now have of us for the usability of our systems are far beyond what we used to have to worry about. That means that you, as a person who is maybe designing a system for a customer call center person, might have to rethink your entire user interface strategy because of something Instagram did, because they're not going to put up with a clunky interface. Why would they? The changing needs, particularly of Gen Z as they come into the workforce, are going to put even more pressure on us to be much more responsive to what our users actually want, and we can't do that if our systems are too difficult to change.
Systems thinking and fitness functions
[00:19:37] Systems thinking in evolutionary architecture: when I look at the different aspects of architecture, we call them the -ilities, and there are over a hundred of them. There's no way that you can maximize all of those different -ilities, because many of them interact with each other. For example, you cannot both maximize the security of the system and at the same time maximize the performance of that system, because frequently maximizing security means additional encryption, and the heavier your encryption is, the more computation you're going to have, and that's going to limit the performance you can achieve.
[00:20:17] So we have to look at the way the components of our architecture interact with each other to manifest business value, but also how these different individual architectural -ilities interact with each other. That's where the notion of fitness functions comes in. What we want to do is be able to specify, for this particular architectural characteristic, this is what constitutes good. Then I'm going to run those fitness functions repeatedly to ensure that my system doesn't atrophy over time.
[00:20:57] That's what often happens if we don't keep track of a particular principle: code and architectures degenerate over time, just like data ages. So we want to be able to look at how these different aspects of our systems work together over time. We use the fitness functions as the guardrails that tell us, OK, this change that I made in the system over here to achieve some particular objective has now worsened some other aspect of my system that I said was important. So I need to do something to mitigate that change. Perhaps I need to reconsider what's important in my system, or perhaps I need to take a different approach to solving my behavioral problem to maintain my architectural characteristics.
[00:21:53] The most important thing about a fitness function, though, is that it's clear whether it passes or not. One of the things that architects have gotten away with for a long time is saying things like "the system must be maintainable" or "the user interface must be intuitive". What does it mean to be maintainable? You and I could actually have a discussion and disagreement about whether a particular piece of code was maintainable or not, whether a particular interface was intuitive or not. So we need to get more precise. Perhaps maintainability is software quality metrics. Perhaps intuitive is the result of some user testing. But there has to be a concrete test where you and I will always agree on whether or not a particular system passes.
Starting from a legacy architecture
[00:22:53] How does this change what I actually do? If you're one of those lucky people who is starting out from scratch, working with a startup, developing a new product with no legacy whatsoever, then it's pretty easy, because you've got a completely blank slate to decide what you really want your architecture to be, and to build it to be exactly that. But most of us aren't that lucky. We are starting with a legacy architecture that may in fact represent several different generations of technology, of technologists, of systems.
[00:23:40] The way I propose people start is to look at where the problems are coming from. Where do you get the most complaints from your users? When do your operations people get really nervous and start canceling vacations when you say you're going to change a particular part of the system? Where do the bugs come from? Identify those things and write a few fitness functions that will allow you to track them. Maybe your software quality is dreadful. Maybe you've got a very inconsistent user experience across your different products. But identify which one of those things is actually causing you the most trouble and start to work on it.
[00:24:27] Very often when we talk about any kind of legacy remediation, the common question I get is, "How do I know it's not going to get battered again? You're telling me I have to clean things up. Are you going to come back in six months and say I have to clean things up again?" That's again where the fitness functions come in, because they allow us to say, "No, it is never going to get this bad again, because we've got this fitness function that will tell us when things are starting to go wrong, so we can bring it back into line." So you want to continually monitor your progress against that particular fitness function.
[00:25:13] Once you get one of those things into shape, go on to the next source of your biggest problem, and always take the time to reevaluate: are those fitness functions still right for you? Perhaps some change has happened that means something is now more important than it was before. This whole process has to be iterative. We have to continue to look at all of the different changes that are happening and reevaluate whether the objectives we've set for ourselves are still the appropriate ones.
Bringing it together: business agility
[00:25:50] How does all of this come together? Our true goal here is business agility. More and more companies are becoming technology companies that happen to deliver something. The person on the last panel from the healthcare lab talked about how they realized they were now a data company, because they just had all of this data. More and more organizations are realizing that technology is a key competitive advantage for them. So we need to have systems that allow the business to adapt to changing customer expectations, to changing developer expectations, to the changing regulatory landscape and to the changing technology landscape. We do that through this process of continuous design and continuous delivery.
[00:26:56] Design thinking has us focus on the outcomes we are trying to achieve, and how the people who are going to benefit from that outcome are going to interact to achieve it. Systems thinking focuses our attention on how the different parts of the system interact with each other to manifest those outcomes, whatever they are, and what we have to do to keep our system in this dynamic equilibrium where we're appropriately responsive to the changes in the environment around us.
[00:27:38] Finally, evolutionary architecture provides us with the tools and the frameworks to think about how we actually keep our systems poised to continually change, so that we can support this more experimental mindset. We're going to make these ideas tangible and then test them in the real market to determine whether they deliver the value we are hoping they do, or whether we have to try something different. So evolutionary architecture focuses our attention on what it takes to support this experimental hypothesis, this test-and-learn cycle, and to be truly responsive to our users, whoever they are, and really manifest the potential in design thinking. Thank you very much. I think we should have time for questions here.

