The aim of our industry is to produce software. That is: listen to our clients' requests and create a system that can does what they wanted, on their hardware (be it a global company IT infrastructure, a smart watch or a thermostat).
This sentence is a typical mission statement:
sounds nice, easy to repeat, and totally useless.
What they “wanted” is mostly unclear, we only know what they have told us. No, we only know what we have understood from what they have told us. “Does it or not?” is a yes/no question. In practice, we can only have a measurement that gives a hopefully objective ratio “how much” our system meets the requirements. We don't just want to create working, but good software. We want to compare different approaches and solutions objectively.
So, we need to measure the goodness, or fitness of our software.
Measurement theory
Fortunately, we do have a sound scientific methodology that can reliably guide us towards a better understanding and judgment, can estimate the “goodness” of our current understanding, and help us further refining it. To explain the title, we will only need the fundamental definitions.
System
In very rough terms, system can be any part of the world that 1: we separated from the rest, 2: interacts with its environment, and 3: changes during this interaction.
Naturally, any software is a system by this definition. However, the actual form of our software is thousands, sometimes millions of lines of source code, configuration, database content, collection of external libraries: gigantic amount of “content” in unclear, but existing relation to goodness. We need to simplify it.
Modeling
We never know “the truth”, but we don't even have to.
Drinking a glass of water is possible only by having the molecules, their atoms and their subatomic particles of my body, the glass and the water in it to follow a proper arrangement for the action; and “the truth” may even be under those levels. However, we have a good enough model of our body, the glass and the water, and we are able to control the process adequately.
Good models give us reliable control – bad models increase uncertainty.
If we know how good our models are, we can estimate the precision of our actions, or add safety mechanisms to our process and achieve a reliable operation in a less reliable environment. Standing is different in a room, in a moving bus or after some drinks, but we can manage such scenarios in a quite wide range by adaptation.
Black box models
These models describe the system from the external perspective only: we can see the environment, the input given to the system and its response. With enough tests, we can say that we know what the system does in certain conditions, and we can build reliable operation on it. However, the same system can give us surprise in untested conditions. The cooling system of our cars works normally, but can also cripple the complete engine in case the coolant freezes. Our black box model can only tell that it works now, but it is safer to look into the box.
White box models
White or glass box models are those that we see through: we know all the internal components and their interaction, so above knowing what it does, we exactly know how and why it does so. Of course, the “absolute white box” is the complete truth itself, which we don't know. The elements inside our white box models are also models, but we assume knowing enough about them to calculate their behavior. We do know about the constant subatomic buzz, but it will statistically never affect the behavior of our car engine. Unlike the fluid levels that we must check regularly.
Analysis
In practice, our models are not completely black or white, but this short introduction to modeling gives a clear statement:
the “darker” our models, the less we should rely on their findings.
With a complete black box we can only have a checklist, we can grow them and repeat testing many times. But without peeking into the box, we can't even know what critical checks we have forgotten about. With a complete white box, we only have to check that the required elements, their parameters and connections are there, because if they are, then the system should work as expected. If it does not, the model gives us clues what parts can cause the problem and what checks are needed to locate it. It can also point at the critical elements that should be regularly checked to make sure the model is adequate.
The consequences are clear:
it is definitely worth creating whiter models, and the opposite:
constant struggle of otherwise motivated and adequately trained participants is likely caused by black box models somewhere in the way.
The development process
Negotiation
To simplify the scenario, our clients asks a question (“can you do what I want?”), and we give them an answer.
In general, we are in competition with others and need the money to continue the operation, so we want to offer more and/or ask for less than the others; while the clients want a working system in the long run but also want to pay less now. Furthermore, adequately refining the question and giving a reliable, honest answer needs a lot of effort and contains serious risk, especially if the competitors' offers are more “optimistic”.
Perhaps it would be too hard to say that within natural business environment our answer will always be the words the clients want to hear, but connected smartly enough to give us backdoors to extend the deadline and price in case we really have to do the job (in short: a lie, or a bit longer: professional sales material). But it would also be too optimistic to assume having a thorough requirement and architectural analysis
before making the deal.
Design
Of course, there are programmers and companies who win a contract because they are ahead of all others by far. They start coding using agile methods, their solution will evolve to perfection naturally and don't need any more philosophy around it. May the Force be with them, but the rest of the world is not so sure of that, so they need objective measurement of goodness, and consequentially, some modeling.
Initially,
we receive a requirement specification. That is, by definition,
a black box model: we don't know the internal structures, don't even know what we don't know about the clients' problems or how to solve it. In order to get a better view, we need to make our models whiter.
But what should we model: the problem or the solution? We have to deal with both, and the two seems to be important alone. Especially, if we want to prepare for later changes from the clients, it is important to clearly see the interaction between the new requirements and our solution. By creating separate task and solution model, the connection must have a clean interface, thus the effects of changes will also be more transparent. Fortunately, we have separate roles for these tasks.
The system analyst deals with the problem model, talks the language of the clients, is an expert in the problem domain. Together with the clients, they refine the requirements, make a white box model of business domain entities, their responsibilities, interaction, and finally, check if the specified data model can behave as it was required.
The software architect works with the solution model: software components, tools, databases, deployment environment. Together with the clients' IT experts, they design the actual system components, data tables, connections to the external systems. This is an iterative process, the actual environment may set needs or limitations to the original requirement, which can be improved and adapted to them.
Finally, we have two "enough white" boxes that show how we solve the task, can be objectively evaluated against the requirements, or adapted to later changes.
Implementation
And now...
we take our white box models and wrap them into black boxes again!
We write source codes on various languages, and create configurations to components that were written in various languages again.
The source code has no defined connection to the structures that we have designed (coding standards and design patterns don't help much), there is no straightforward way to validate the result.
Each measurement is as good as its worst segment.
Returning to a black box model means the complete, so far controlled development process is almost as bad as doing it all with no planning. In practice, the expensive design phase seems to be a waste of money and resources in meaningless discussions and brainstorming.
Some of the lucky startups may overtake the highly organized companies even in the quality of their products (perhaps because they do the job at their desks that the big ones outsourced to cheaper but less motivated guys).
Houston, we've had a problem...
Solution
If this problem is so obvious, why don't we have a solution already? In fact, we do, on many levels.
Sedatives
Of course, we have tons of static and dynamic code analyzers, unit testing, integration testing, continuous deployment tools, etc. This does not help in the fundamental problem: we put our solution into a black box, and all quality measurements are just external checklists without understanding the internal structure.
The tools that peek into the program structures by detecting the graphs show useless complexity, gaining useful information from such a report is on the same magnitude as asking a professional to write it again.
Those that try to enforce connection between design and implementation like UML tools are very rarely used because they limit the freedom of both the designers and programmers without providing a clean process model for the transformation.
Considering all this, the current failure / delay rate should not be a surprise. Even if we gracefully forget about the 99% of startups that die without notice.
The Good Old Days
Decades ago, when there were much less programmers and much weaker hardware, we could not afford wasting so much resource on writing code, so for example, user interfaces were created by resource editors. There were much less hype around user experience, but those systems were quite usable.
Today
We have a renaissance of declarative user interfaces (Apple never left it, Microsoft, Google, Mozilla and many other vendors create their own user interface configuration tools). Application structure is also going out to configuration, these are the cloud based solutions, Inversion of Control Containers, etc.
There are also many systems that allow their users or admins to configure their operations. Security systems are configurable in many environments; we have workflow engines, task and project management tools, etc. All they can do can also be done by typing some lines of source code, but that is unsafe, it is better to have some visual editor to click and drag together the process in a guarded and validated environment.
What is common in these tools? They all bring the white box model back to the implementation level!
Is it a problem to solve at all?
Our economy is moved by the needs.
Education system is happy that we “need” legions of programmers who should type source codes to the always changing and ever newest platforms, “solving” the same problems again and again. This looks good in marketing campaign and political slogans, keeps the business running. Solving this issue would change the IT world, and is not compatible with any of our current business models.
Even if we could create the technology, we are not ready for its consequences.
Summary
- Software became fundamental element of the human civilization, its quality is critical;
- We can check and improve quality only if we can measure it;
- Measuring depends on the models that we create;
- Reliable checking, efficient problem finding, estimating the side effects of changes only available with white/glass box models, while black box models only allow guessing by experience;
- The requirements are black box models, that we can make white by expert problem and solution modeling, but traditional implementation puts it back to a black box again;
- Advanced computing technologies have one thing in common: they allow white box modeling in implementation.
So...
If you want to build a reliable system, write less code!
And use libraries that also follow this approach, because the quality and flexibility of your system is related to the same attributes of your weakest component.