#begin

David starts this chapter with yet another definition: “Incremental design is directly related to any modular design application, in which components can be freely substituted if improved to ensure better performance.” David says that incremental work is focused on delivering value progressively and taking advantage of modularity and componentization of our systems.

Incrementalism differs from iterative workflows by building a system and releasing it piece by piece. Iterative workflows are about reining and improving something over a series of iterations. I think this makes perfect sense.

 

Importance of modularity

The first section of this chapter is about the importance of modularity. I think that we have talked about modularity a long while already and here it is again. We talked about it in during clean code, a philosophy of software design, the SOLID principles and much more. So here we go again. Let’s see what David thinks is so important about modularity. I bet it’s good!
David says that modularity is an important idea regardless of being important in the software industry. It’s been important since the stone-age. These stone-age craftspeople crafted axes from wood and stone. This is… a modular system at heart. If the ax-head breaks, or the handle breaks he or she could just make a new one. I think its pretty cool to refer to this kind of ancient modular systems. But to refer to one more modern; David mentions the Apollo spacecraft was composed out of modular systems. Even the ISS is modular. All components are launched into space separately. Imagine if they would have needed to launch the entire ISS into space in one go. How big of a rocket would that have needed?

So, modularity had a number of advantages. The core idea is that it means that each component could be built to focus on one part of a problem. This way you can isolate changes, purpose, testing and production. If you make one large thing then the cost and duration of it would not make much sense. Even the replacability would suffer. Imagine that if on of the lights of your car broke, you needed to replace the entire darn car. That would not make much sense and would be far to expensive. You just want to replace that light and move on with your life.

The same goes for software. You want to divide your software, your problem in small parts. You want to isolate, encapsulate and separate your problem into multiple smaller problems (you can even subdivide as far as you want). Modularity allows people, teams, companies or even counties to work independently. As long as we make some rules about integrations we should be able to couple things in the end. This is true for software but also for production of physical goods like fighter jets, air-craft carrier ships or space-crafts for example. Different counties pitch in to make separate parts of these multi-million projects.

If you have been reading my blog for a while you must be aware that I’m a sucker for component based design or plug-in architectures. So modularity is something I feel I really important for good and clean software design.

David seems to agree and he also mentions that micro-services are not the only way of reaching this component based architecture. We just need to take (architectural) boundaries seriously. This has nothing to de with micro-services. We can make a centralized architecture respect its architectural boundaries as good or better than a micro-service architecture. However, David says he’ll cover this in later chapters of the book.

 

Organizational Incrementalism

The next section is about the benefits of modularity; it’s isolation. This is really at the heart of modular design. You can focus on a single requirement or group of requirements that focus around a single aspect. Internal details are hidden and irrelevant of other modules. Encapsulation and information hiding show their foothold here. This is important for both technical and organizational reasons.

A modular approach allows teams to work more independently. Each team, can make incrementally small steps towards their own goals, regardless of what other teams are doing. This is very important to understand. You just don’t need to coordinate with each other as much when we apply a modular mindset. I’ve written a lot about this before in both my review of A Philosophy of Software Design and my review of the OOSE book. You can find both on my blog :).

Additionally, an incremental mindset stimulates an incremental approach to culture and organizational change. I think David makes a nice observation here since this can be really valuable when adopting some new technology or process. I think we all heard the stories of companies switching from waterfall to agile. This change process is still ongoing! David also specifically mentions that companies find business transformation notoriously difficult.
If we want to enable and support creativity we need to leave room in the process and policies that structure our work for creative freedom. Especially in design engineering and software engineering we need people to be able to make changes – change they mind – without asking permission to any person or group outside.

I believe this is indeed very important. This is how Dephion effectively managed its employees. Some high-level requirements were given and how you made it happen was up to you. I really liked this way of management, but I could also recognize that some people couldn’t handle it. Some employees just really need guided processes instead of a loosely managed one.
David also throws in a quote from a legendary book in software called “The Mythical Man Month, by Fred Brooks” and it goes as follows: “If a 200-man project has 25 managers who are the most competent experienced programmers, fire the 175 troops and put the managers back to programming”.

Now there is a lot truth in this and I bet that Elon employed the same philosophy with the layoffs at Twitter. As a matter of fact, we are seeing immense layoffs everywhere in the software industry. The Covid bubble finally burst and all people who where hired during the hiring spree are out of a job now sadly enough.
But to get back to the book… To carry our (large) organizational change you really do need to start small. Teams need to be small and they need freedom to explore and make their own changes. Agile teams of 25 people are far too large. An agile team should be about 4 to 8 people in my opinion. When you have more people, just make more teams and have them coordinate properly. All this junk about SAFE is nonsense… just keep the teams small and communicate. SAFE tries to fit agile into a larger scale but its never been intended to be like that. There are many good concepts about SAFE but just as with Scrum, don’t emphasize on the rituals and other crap.

David ends this section with a very strong argument and I’ll quote it directly: “The key transformation then that most organizations need to make is toward greater autonomy for people and teams to deliver high-quality, creative work. Distributed, incremental change is the key”. How awesome is that!? I mean any software professional basically knows this but there’s often other people in the way like managers or SCR*M ‘masters’. So stand your ground and try to make things happen!

 

Tools of incrementalism

The next section is about the five key principles David uses for managing complexity. He defines them as the following:

  • Modularity
  • Separation of concerns
  • Refactoring
  • Version control
  • Testing

If you have been any longer than 10 days in the software industry, this will sound familiar. If not, take what-ever book on software development and find these five principles explained in some form or other. These are such fundamental concepts that any will know them. But let’s quickly repeat them and see what David wants us to know about these topics.

David says that incrementalism and modularity are deeply linked. Incremental change requires us to make changes with limited impact. Working on improving the modularity of a system is always a good idea. This also refers to separation of concerns. When things are properly separated they can be modularized more easily. If you got intertwined with the flying spaghetti monster in the sky, one cannot simply, untangle that big-ball-of-mud.
So that’s two out of five covered. I know it’s a bit short but don’t worry, we will take a detailed look at these principles in future chapters. But this leaves 3 subjects for David to discuss.

David says that you can adopt the left over 3 to make modularity and separation of concerns happen.
He first mentions refactoring. It’s a very safe technique to alter the structure of the code without changing it’s function. This is very important to understand! Don’t refactor code while also changing the functionality. Do one first, then the other! David also rightfully mentions the fact that good, solid refactoring skills are often undervalued. And… well, I agree. As a developer we are constantly refactoring to fit old code into new patterns and architectures. I also believe that knowing your favorite IDE’s keybind shortcuts is important to be able to constantly refactor. If you don’t know the keybinds you will probably not rename a method as often, or extract a method or class from existing code. So learn your keybinds!

David also says that version-control is fundamentally important to doing fine-grained incrementalism. You will always be able to work from, and roll back to, a “safe-space” and combined with CD you will have incredible momentum.

Lastly he mentions testing, of course… But he specifically mentions automated testing. This will allow you to move fast, incrementally, with significantly more confidence. People really need to make automated testing part of their daily working practice. When you focus on testing your code properly you will notice you produce code much faster and are switch directions as well. Especially TDD demands tiny executable modifications. Each tiny specification (test) describes the necessary changes required to make the test pass. And when the test finally passes, you refactor it while keeping the tests running in the background.

David then also reiterates the notion that testable code is inherently modular since you need to reach into the code while running the tests. And no, reaching into the code by means of reflections during testing is not what David means. But good, TDD code requires you to inject testable dependencies into your code. So you will think twice about initializing private or protected members in constructors. Maybe you would just want to inject these dependencies.

 

Limiting the impact of change

David then talks about how to make a system’s architecture support incrementalism and modularity. He mentions the Ports & Adapters pattern, how, well… expected 😀 Ports & Adapters, Hexagonal or Clean Architecture always seem to emerge when talking about proper architecture that support modularity, separation of concerns and testability. I’m a sucker for such “plug-in” based architectures as well, if you haven’t noticed from earlier blogs.

David makes a very nice comment on these kinds of architectures which I’ll quote directly: “We should always treat these integration points, these ports, with a little more care than other parts of our system because they cause more pain when things need to change here. The Ports & Adapter approach gives us a strategy to embody that “more care” in our code.

I think this idea is true gold. I’ve never heard any of the software guru’s state it in such a way, not even Uncle Bob himself. He might have talked about it, but never used the same language. I mean, the architecture gives us a strategy to embody more care in our code. That’s really interesting.

Lastly David mentions that ports & adapters is technology agnostic. No matter your language or programming paradigm you can use a ports & adapters approach to care about your code.

 

Incremental Design

David says that they way to incremental design is some form of an agile approach. What-ever you choose, you should work incrementally in small iterations towards the greater good. Mostly because, if you take an agile approach, you can start your work before you have all the answers. We can both work, and learn incrementally during these small iterations which is really at the heart of this book by written by David.

David then says something I think is pretty interesting and worrisome at the same time and I’ll quote it: “This challenges many software developers preconceptions. Many people that I (David) talk to struggle with the idea of being able to write code before they have a detailed idea of the design they want to create”. I think this is worrisome because we are software professionals need to extract the functionality from the requirements given by our clients and our design will emerge from and during our iterations. Just start out small and lean and specialize the design as you gain more knowledge. That’s always a good approach.

Even more so, I can’t imagine an approach that would make more sense.
Then even more worrisome is the following: “Even more (people) find the idea of incrementally architecting a complex system almost inconceivable, but both of these ideas are at heart of any high-quality engineering approach.” I can’t wrap my mind around how people might think this, yet still promote agile workflows. This is a core idea of how agile is supposed to work. So, I’m curious about what people David is talking about. It seems a bit unreal (not the engine :D) to me.

David also makes a pretty funny comment about this as well. He says that complex systems don’t just spring fully formed out from the mind of some genius creator. Haha yeah, that’s true. Complex systems grow into it. They are about deepening understanding over a (long) period of time.

This is hard work and simply cannot be done pre-advance on a whiteboard. Anyone who tells you otherwise is either full of shit or has never really written a complex system.

We need to embrace incremental design in order to get anywhere. We need to move step by step to manage complexity. If we adopt ideas that strengthen modularity and ease of change we open doors to unexpected change in the future. Organized code is easier to change!

David says that one of the most important aspects of the core he produces is that the code should be able to change when he learns new things. His goal of the code is to be able to grow incrementally to fulfill its function as that function becomes more clearer over time. And I agree again! We can have all the coding standards and guidelines we want, but if we cannot change the code when new insights are gained it’s worthless in the grand scheme of things.

#end

01010010 01110101 01100010 01100101 01101110

Hey, sorry to bother you but you can subscribe to my blog here.

Never miss a blog post!

You have Successfully Subscribed!