2024 Public Training Schedule
December 9 – 12, 2024 – Agile Analysis and Design Patterns
Half-Day Sessions
(c) 2024 To Be Agile
When I look at the systems around me I noticed three kinds. There are simple systems, there are complex systems, and there are complex adaptive systems.
Most of us are familiar with simple systems. They have a direct cause and effect relationship that can be easily traced. Other systems are less direct.
Complex systems are systems that have emergent properties. They don’t follow a simple cause-and-effect relationship. The weather is an example of a complex system. Complex systems often sit on the edge of chaos. I find that very few people understand the nature of complex systems.
Finally, there’s a third kind of system that I notice in the world, which is complex adaptive systems. Living organisms or communities of organisms can have this emergent property. Interestingly, biologists are quite skilled at dealing with these kinds of domains.
Currently, computer systems are complex systems. But many people think of computer systems as simple systems. As a result, there’s a great deal of misunderstanding about computer software and how it is supposed to operate.
Complex systems are defined by how they’re organized. Their elements are oriented in ways that make them most accessible for their desired purpose. Therefore complex systems have a purpose or tendencies toward certain behaviors. Understanding the nature of complex systems will be an important part of building software in the future.
Complex systems, like software, have a lifecycle and we’re just beginning to tune in to the importance of the lifecycle in our software. As we learn more about how to build maintainable software, our code will be able to be more easily repurposed in the future as the needs of the user changes.
Complex systems are composed of simple elements that are combined in complex ways. If we have three different choices, each with two options then we have 2^3rd or eight potentially different outcomes.
This can grow rapidly. For example, 10 options mean 1024 outcomes, potentially. That’s 1024 tests required to guarantee that we’re combining these options in ways that are valid.
Most programming languages give us the capability of encapsulating both data and behavior so we can better manage combinatorial issues. This is one of the most powerful aspects of objects because we can guarantee that they only interact with the rest of the system in predefined ways. This limits the kind and number of bugs that can be introduced to a system and it also limits our testing requirements.
If we can break complex systems down into composite parts then we’re often better equipped to manage these systems and understand them so we can reproduce them.
Virtually all complex behavior can be seen as composed of simpler behaviors that are enabled to combine in complex ways. When a complex system is understood in this way then it becomes much more straightforward to understand and work with.
Previous Post: « Trade-Offs
Next Post: Making Code Testable »