We develop software thinking on the whole thing upfront, instead of thinking on the small parts that compose it.
All the other engineering areas, such as electronic engineering, have created tools, methods and processes that help them to create parts, pieces and components that are used as simple units capable of providing their functionalities without causing strong dependency.
These small pieces are also tested prior to their construction and they all have public interfaces used to expose their functionalities and properties to other components.
When used together, these pieces form complex systems, equipment and all sort of things the human being have created over the time.
In this article, I talk about software componentization, with a brief passage thru single responsibility and the importance of testing in the development process.
Each Friday, at Mindworks, our development team meets for our Mindtalk.
The Mindtalk is an informal meeting in which each member of the team talks about any subject. We had great moments where we found ourselves talking about physics, black holes, chaos theory and time traveling, trying to relate those subjects to software development problems... Guaranteed fun for sure!
Unfortunately, we didn't make it up for the last Friday...
But it's ok. We will do it next week...
Anyway, I had even chosen the title for my lecture: "Hardware: The materialized software".
But what do I mean by that title? Materialized Software? What is it all about?
It's simple! My goal was talking about software componentization and, between the lines, talking about software architecture with a slight mention on Test Driven Development (TDD).
After thinking a bit more, I decided to change the title of my post (and lecture) to "The Capacitor".
Do you know what a capacitor is?
Those who know a little about electronics know what it is.
For the ones who don't, here it is, according to the Wikipedia
"A capacitor (formerly known as condenser) is a device for storing electric charge" :/
In fact, most of us do not need to know what a capacitor is, but another truth is that this type of electronic component is present in every single electronic device we use nowadays, as well as the resistors, transistors, diodes, etc…
Ok, but what does this have to do with software?
A capacitor is a component... It was designed to accomplish a specific task and it exposes a common interface which allows other components to use its "services" without strongly depending on the capacitor itself.
My point is: If another component uses the functionalities of a capacitor, when that capacitor becomes defective or, for some reason become obsolete, all we need do is replacing the defective capacitor by another that implements the same interface.
Maybe the engineers that will read this post will also crucify me for these statements, but I'm pretty sure about it.
Even if the defective capacitor causes the failure of other components, we can still replace the defective components by others that implement their public interfaces!
If these components fail, we don't need to drastically change the whole device. We just need to replace the defective parts...
If you have not realized what this sstatement has to do with software development, please stop and think! I quoted, implicitly or explicitly, the words "component", "interface", "functionality", "dependency" and "replacement" ... All the words are somehow related to software development, right?
The electronic engineering brilliantly componentized their devices.
Better yet: These components are all tested before they are built! The electronic engineering was able to create methods and tools that allow us to test the functionalities and responsibilities of these components prior to their construction.
The electronic engineering mastered the art of creating and exposing the interfaces of these components, so that the mechanisms used for testing don't require a component to be ready (physically speaking) before it can be tested ... The tests are so accurate that the components are produced close to perfection. They are physical copies of their specification.
Another interesting thing is that all we need to know about the component comes down to the functionalities exposed by its public interface ... Nothing more! Does it remind you of some OO concepts?
Now the most important: What we do with these components?
We create things!
Many components are combined to create complex things! Things like your computer, your TV, your cell phone...
What bothers me is that I rarely see a developer who knows about componentization, developers who think on the small parts of the whole software, that are able to test the specifications of these parts, that able to, at least, separate and isolate a software component, taking into account its responsibility.
I see developers still creating "things" that are too complex to maintain, impossible to test and even to understand...
Another mistake we made occurs when we sell our work ...
If you go to a store to buy a computer, you will be greeted by a vendor who, theoretically, knows everything about the available products.
You will perform a set of questions in order to be sure on the quality of the product. If you are a little geek, you will ask some technical questions, such as: What is the clock of the processor? Is the memory of type DDR3? Is the video card good for modern 3D games?
But I guarantee that you will never ask if the 10 mF electrolytic capacitor, which is next to the PNP transistor and the 10 ohms resistor, supports 105 ⁰ C!
It does not matter to you, right?
All you need is the computer that meets your expectations...
But the developer is a smart guy ... He is above average ... He is the master of reasoning...
So he eventually talks more than he should... He will think and plan for the whole thing, and he will describe all the capacitor's properties and functionalities to the client!
His purpose is to show off his high intelligence and above normal wisdom that will enchant the customer...
He forgets about all the traps he is putting himself in ... About all the problems to come ... He forgets that the customer will charge him for everything that was said...
Do not get me wrong! I am not defending the idea of hiding the truth from the customer! The opposite of this ...
For me, the biggest problem is that he forgets to say what is really important:
“Software development is an extremely complex task”.
He forgets to say that, in most cases, the construction of a software involves the construction of its small components. In most cases, he doesn't have the capacitors, transistors and resistors ready to use. He doesn't have their interfaces exposed and tested.
He forgets to say that he does not even have the unit tests for these components and many times he doesn't even know for sure what he is going to build!
When it comes to the domain of an application, he will have to create almost everything*, just because the domain is unique for each project.
Even so, the developer is still selling his work as if it was a product that must be assembled and delivered within a "defined time and cost" ...
So, here are the questions for discussion:
- Why we don't follow the steps of the other engineering?
- Why we don't learn with them?
- Why do we continue to think of software as a whole instead of thinking of its small parts?
- Why we don't test before building? (This is my favorite one)
- Have you ever played Lego? :)
The ones who have something useful to contribute, please comment. The ones who don't, please go visit YouTube! :)
See you later!
* Can we reuse pre-existing "parts"? Yes, of course! But the application domain is always unique. It is not repeated from an application to another. Yet, we must componentize the domain, since the benefits of componentization are not limited to code reuse. Keeping small pieces with single responsibility makes the maintenance and testability of such pieces a less complex task.