|
| 1 | +--- |
| 2 | +title: "Prerequisites for evolutionary architectures" |
| 3 | +excerpt: "Designing software that is flexible and changeable is arguably the most important architectural property." |
| 4 | +layout: single |
| 5 | +comments: true |
| 6 | +read_time: true |
| 7 | +share: true |
| 8 | +related: true |
| 9 | +tags: |
| 10 | + - architecture |
| 11 | + - methodologies |
| 12 | + - software development |
| 13 | +header: |
| 14 | + overlay_image: /assets/images/2020-05-20-Eng-Arch-Revised-Gradient.jpg |
| 15 | + overlay_filter: 0.25 # same as adding an opacity of 0.5 to a black background |
| 16 | + caption: "Changability is the most important architectural propery" |
| 17 | + teaser: /assets/images/2020-05-20-Eng-Arch-Revised-Gradient.jpg |
| 18 | + |
| 19 | +--- |
| 20 | + |
| 21 | +# Prerequisites for Evolutionary Architectures # |
| 22 | + |
| 23 | +Designing software that is flexible and changeable is arguably the most important architectural property. I often get |
| 24 | +other software architects saying “What about performance?” or “What about security?” I’m not saying these other |
| 25 | +properties are not important to consider early on. They are. However, if we optimise our architecture for change |
| 26 | +(evolvability), when we discover a performance issue or a security vulnerability we can change our system to help |
| 27 | +address it. The ability to respond quickly to issues like these is exactly what makes evolutionary architecture so |
| 28 | +essential. |
| 29 | + |
| 30 | +## What properties are important in evolution? ## |
| 31 | + |
| 32 | +You can think of the way a species adapts to its environment in the same way that you think of evolutionary |
| 33 | +architecture. To be successful, animals need to produce new generations with advantageous traits, respond to feedback |
| 34 | +from the environment, and leave room for failure by falling back on what works. |
| 35 | + |
| 36 | + |
| 37 | +Software is similar. You need to make sure it’s adaptable and that you’re making changes to your system based on what |
| 38 | +works. There are a few key ways that we can create these adaptable architectures: Pick constraints to support rapid |
| 39 | +change |
| 40 | + |
| 41 | +* Separate the concepts of deployment from release |
| 42 | +* Gather and share fast (appropriate) feedback |
| 43 | + * In development |
| 44 | + * In production |
| 45 | +* Build a responsive culture |
| 46 | + |
| 47 | +## Pick your constraints to support changeability ## |
| 48 | + |
| 49 | +In order to support evolution in software we need to be aware of the constraints of the software and the environment |
| 50 | +that the software operates in. |
| 51 | + |
| 52 | +As software architects and developers we have control over some aspects of the environment we build and run software in. |
| 53 | +Here are some of the constraints we might want to consider to support change/evolution. |
| 54 | + |
| 55 | +### Pick the right building materials ### |
| 56 | + |
| 57 | +At the start of my career, I believed that any Turing complete programming language was equivalent to any other and the |
| 58 | +language picked was not that important. As I’ve become exposed to more programming languages, paradigms, libraries, and |
| 59 | +frameworks I’ve realised that the ‘building materials’ we pick have a huge impact on the inherent properties of our |
| 60 | +software systems, especially on changeability. |
| 61 | + |
| 62 | +When you start building a new system, consider the following: |
| 63 | + |
| 64 | +* Favour languages, libraries, and approaches that allow you to parse the data you need from larger more complex |
| 65 | + structures. |
| 66 | +* If you are using a strongly statically typed language consider using a language that infers type to reduce changes you |
| 67 | + need to make through your code base. |
| 68 | +* If you use a weakly typed language, think about what libraries or idioms you may need to add constraints on the types |
| 69 | + of changes allowed and how they can occur (otherwise you are in the wild west and anything goes) |
| 70 | +* Favour immutable data structures - immutability constrains the way state can change in your executing program thus |
| 71 | + simplifying reasoning about state, especially in a multi threaded environment. If your language doesn’t support |
| 72 | + immutable data structures as the default there are plenty of libraries out there for most languages (look for |
| 73 | + persistent immutable data structures that reuse memory). |
| 74 | +* Favour declarative approaches over imperative ones. |
| 75 | +* Do you understand the problem well enough to pick a framework early on or should you maintain the flexibility by |
| 76 | + constructing your solution using small libraries? Pick tools and approaches to support feedback and deployment |
| 77 | + |
| 78 | +In order to evolve, our software needs to be easy and quick to release, and we need feedback about it’s appropriateness |
| 79 | +during development and while in production. Therefore we should pick tooling and approaches that support those |
| 80 | +properties. Here’s a non-exhaustive list of some things to consider: |
| 81 | + |
| 82 | +* Continuous integration |
| 83 | +* Continuous delivery |
| 84 | +* Dark deployments |
| 85 | +* Canary deployments |
| 86 | +* Blue/green deployments |
| 87 | +* Automated testing |
| 88 | +* Automated alerting/monitoring |
| 89 | + |
| 90 | +Though it may sound frightening, it can be useful to incorporate production-testing alongside these other testing |
| 91 | +methodologies. Sometimes testing less and allowing something to alert if it fails can be a risk worth taking or even be |
| 92 | +advantageous in detecting the actual problem in production. Production is the only real test environment. However, this |
| 93 | +is a risk judgement dependent on the problem, architecture etc. |
| 94 | + |
| 95 | +Implementing some or all of these approaches can enable you to respond to a bug by fixing forward fast rather than |
| 96 | +taking a more defensive approach of testing excessively and reverting if a bug occurs. |
| 97 | + |
| 98 | +### Stay small as long as possible ### |
| 99 | + |
| 100 | +For every additional person involved in writing a system, you exponentially increase the communication paths on your |
| 101 | +team. If you can keep your teams and the number of teams as small as practical you reduce the amount of communication |
| 102 | +and coordination required to implement each change. |
| 103 | + |
| 104 | +I would extend this principle to keeping the number of teams as small as possible too. Working with a constraint of a |
| 105 | +limited number of (the right) people will result in innovative approaches to solutions. Just make sure that one of them |
| 106 | +is not to work longer hours (therefore consider an upper limit on working hours as another constraint!). |
| 107 | +### Organisation-wide systems thinking ### |
| 108 | + |
| 109 | +Even the most ‘brick and mortar’ businesses do a lot if not the majority of their customer interactions via software |
| 110 | +(even if it’s B2B) and therefore your organisation should think of software as the primary means of revenue generation. |
| 111 | + |
| 112 | +Forcing ‘project thinking’ onto software development is a bad idea. Trying to implement a number of ‘features’ to a |
| 113 | +deadline and budget is often necessary but if every change to your software happens this way then that short term focus |
| 114 | +never leads to longer term consideration of the product or platform and it’s quality properties. |
| 115 | + |
| 116 | +You can use projects to manage budgets but always think about the product or platform when choosing what to implement. |
| 117 | + |
| 118 | +## Separate deployment from release ## |
| 119 | + |
| 120 | +In order to evolve, our software has to generate a new ‘mutated’ generation. If you can deploy your changes in a canary |
| 121 | +deployment or even, depending on the change, a dark deployment you can test the change in the only realistic test |
| 122 | +environment, production. |
| 123 | + |
| 124 | +Without mandating a specific architecture (e.g. microservices, event streaming, modular monolith) Domain Driven |
| 125 | +Development (DDD) and Event Storming are very useful in determining the boundaries of deployment units. |
| 126 | + |
| 127 | +Don’t consider static modelling in isolation If you build a data, component or class model in isolation you often focus |
| 128 | +on the wrong attributes. For example, you can model hundreds of attributes about a student in a university but the |
| 129 | +bursary system probably only cares about identification, fees and payment information plus events that change the state |
| 130 | +of those attributes whereas student services care about much more personal information. Use the dynamic aspects of the |
| 131 | +system to guide what information is important to that context. |
| 132 | + |
| 133 | +Thinking about events and flows often leads to discovering the components (deployment units) of the system. Each high |
| 134 | +level process that sends and/or receives a message is a potential component. |
| 135 | + |
| 136 | +Here is a list of techniques that can be useful for separating deployment from release: |
| 137 | + |
| 138 | +* Feature toggling |
| 139 | +* Branch by abstractions |
| 140 | +* Continuous Integration/Continuous Delivery |
| 141 | +* Immutable servers – packaging aspects of the runtime environment in an immutable image makes deployment and rollback a |
| 142 | + much less risky proposition. |
| 143 | +* Schema on Read DB's – they make adding data in a deployment much easier provided you always ‘accrete’ (or add to) your |
| 144 | + schema. |
| 145 | +* Consider always API ‘accretion’ – Always adding to your APIs and only logically deprecating functionality or data is |
| 146 | + easier for client applications to deal with and a ‘breaking’ change is really a new API so treat it that way. Think |
| 147 | + about how to deal with data returned if you don’t have full control over your clients and can’t trust they parse only |
| 148 | + the data they need (e.g. do all clients implement tolerant reader pattern?). This is where using GraphQL even in |
| 149 | + service to service calls can have benefits as it’s inherent constraints assume only returning what’s requested (and |
| 150 | + you get schema introspection). |
| 151 | + |
| 152 | +## Fast appropriate feedback ## |
| 153 | + |
| 154 | +I like to think about software as ‘living’ inside increasing larger ecosystems in the same way that biological organisms |
| 155 | +do. |
| 156 | + |
| 157 | +<figure> <img src="/assets/images/ecosystems_feedback.png"> <figcaption>Illustration 1: Ecosystems |
| 158 | + feedback.</figcaption> </figure> |
| 159 | + |
| 160 | +Illustration 1 shows the layers of ecosystems that our software ‘lives’ in. We can see from this illustration that the |
| 161 | +inner ecosystem can be affected by a change in one of the outer ecosystems but, conversely, the inner ecosystem can |
| 162 | +cause a change in the outer ecosystems. |
| 163 | + |
| 164 | +Additionally not shown in this diagram is the concept of the frequency of the feedback. |
| 165 | + |
| 166 | +* Software environment feedback is measured/sampled in microsecond/seconds/minutes/hours. |
| 167 | +* Team/product environment feedback is likely to be measured/sampled in days or weeks. |
| 168 | +* Organisational/departmental environment feedback is likely to be measured/sampled in weeks or months. |
| 169 | +* World wide/market environment feedback is likely to be measured/sampled in quarters/bi-annually/annually. |
| 170 | + |
| 171 | +Without going into an exhaustive list of metrics and techniques that might be used to provide feedback the following |
| 172 | +illustrations give you some ideas of what you might want to consider, but as always, there’s no silver bullet and YMMV. |
| 173 | + |
| 174 | +<figure> <img src="/assets/images/microecosystems.png"> <figcaption>Illustration 2: Software environment |
| 175 | + metrics.</figcaption> </figure> |
| 176 | + |
| 177 | +The micro-ecosystem translates to the runtime environment and the software development practices used in developing the |
| 178 | +software. The illustration above gives some metrics and techniques that can provide feedback at that level. |
| 179 | + |
| 180 | +<figure> <img src="/assets/images/biotope.png"> <figcaption>Illustration 3: Team/product environment |
| 181 | + metrics.</figcaption> </figure> |
| 182 | + |
| 183 | +The biological concept of a Biotope (or habitat) translates to the team and/or product that the software is a part of |
| 184 | +and Illustration 3 gives some examples of metrics and techniques for feedback at this level. |
| 185 | + |
| 186 | +<figure> <img src="/assets/images/biome.png"> <figcaption>Illustration 4: Org/dept environment metrics.</figcaption> |
| 187 | + </figure> |
| 188 | + |
| 189 | +Illustration 4 shows some examples of metrics and techniques to provide feedback at the organisation or departmental |
| 190 | +level. |
| 191 | + |
| 192 | +<figure> <img src="/assets/images/biosphere.png"> <figcaption>Illustration 5: World wide/market environment |
| 193 | + metrics</figcaption> </figure> |
| 194 | + |
| 195 | +Finally, Illustration 5 gives examples of potential feedback mechanisms at the level of the target market or in other |
| 196 | +markets. |
| 197 | + |
| 198 | +As you can see the example metrics I’ve suggested are a mix of measurements of the processes for producing/running |
| 199 | +software and the measurement of external factors that may impact or be impacted by that software. It’s important not to |
| 200 | +concentrate on only measuring the things you can change directly but also measure the factors that you only have |
| 201 | +indirect influence over to enable your software to evolve to those pressures too. |
| 202 | + |
| 203 | +Although I’ve given a number of metrics you should start by identifying between 2 and 5 metrics in each ecosystem level. |
| 204 | +I also try to map lower-level metrics to metrics in the ecosystem above in order to ensure that a metric is driving the |
| 205 | +desired behaviour. |
| 206 | + |
| 207 | +### Building a responsive culture ### |
| 208 | + |
| 209 | +Lastly, none of these techniques can be implemented effectively without a culture that embraces, seeks out, and thrives |
| 210 | +on change. The typical characteristics of this type of culture are all the things you see in agile and lean |
| 211 | +books/courses: |
| 212 | + |
| 213 | +* No blame culture |
| 214 | +* Empowerment of teams/individuals |
| 215 | +* Delegating responsibility and authority for entire problems to teams |
| 216 | +* Smaller teams to reduce communication networks |
| 217 | +* Clear, high-level targets/goals with clear measurable objectives (see ‘Fast appropriate feedback’) |
| 218 | +* etc. |
| 219 | + |
| 220 | +However, I think it’s important to emphasise this culture is something that needs to be pervasive throughout the whole |
| 221 | +organisation. It’s all very well having a software development team or department that has this culture but if the rest |
| 222 | +of the organisation interfacing with that group is in a strictly hierarchical command and control culture this will |
| 223 | +cause friction and ultimately be much less effective in responding to change. So what do you do if the organisation is |
| 224 | +not on board with this culture? |
| 225 | + |
| 226 | +Ideally you can convince the ‘C’ level management and the board that this culture is required and demonstrate how to |
| 227 | +achieve it through some ‘localised’ success by adopting some of the strategies suggested. |
| 228 | + |
| 229 | +However, I have found some success in tying the metrics that the ‘C’ level management look at, which tend to be either |
| 230 | +in the organisational/department environment or world wide/market environment, to the metrics in the ecosystems below to |
| 231 | +show how ‘moving the needle’ in one metric impacts the others. I’ve also found that this helps start the conversation |
| 232 | +about software not being a ‘cost’ to the organisation but it’s primary means of revenue generation in the future for |
| 233 | +most organisations. Demonstrating that software is not only about automating processes but about creating new ways to |
| 234 | +interact with customers in new markets. This in turn can provoke a move away from project focused development towards |
| 235 | +product/platform focused development. |
| 236 | + |
| 237 | +If you’re trying to convince the upper management/board of something, demonstrating how it impacts the metrics they care |
| 238 | +about is hugely powerful. |
| 239 | + |
| 240 | +## Summary ## |
| 241 | +I’ve covered a lot of ground in this post. However, if there are only three things you take away from this I hope they |
| 242 | +would be: |
| 243 | + |
| 244 | +* Pick a couple of properties in each ecosystem that you wish to change and identify metrics for them (preferably |
| 245 | + linking lower level metrics with those higher up the ecosystems ‘ladder’) |
| 246 | +* Pick a couple of ‘constraints’ that you don’t yet implement that might help support the required changes above and |
| 247 | + think about how to implement those constraints |
| 248 | +* Use the constraints you pick to guide the ‘materials’ you use and the ‘culture’ you need. For example, if you want to |
| 249 | + deal with changes in data/message structure more effectively you may decide to concentrate on structural typing and |
| 250 | + accretion only approaches to interfaces and data storage. This might lead you to picking certain languages/libraries |
| 251 | + that support structural typing, easy parsing of data, tolerant reader pattern and immutable databases. |
| 252 | + |
| 253 | +There’s no one-size-fits-all solution when it comes to evolutionary architecture. Instead, it’s important to gather |
| 254 | +feedback over an appropriate timescale, adjust your approaches as you learn and grow, and don’t try to change everything |
| 255 | +all at once. I hope this post has given you some food for thought and a few practical approaches to try. |
0 commit comments