When explaining some nuances of my job to a person outside of the IT world, I sometimes use analogies to house building, as this is a field, to which almost everyone can relate to. I’ve also heard other analogies, like for example car manufacturing. Those analogies may seem intuitive and appropriate, as computer science in general is considered an engineering course in universities, so it seems only natural to compare it to other technical, engineering fields. But is it right to say so?
Computer sciences often include mathematics in their curriculum and that’s fair, as to understand algorithms you should have at least some mathematical knowledge. But to be honest, not so many of us deal with pure algorithms in day to day work. We ship software. We implement new features. But do we have any critical measures at our disposal? Let’s look at some.
Test coverage – you can have as much as 90% or more coverage for your business layer of application, but this does not mean your application is 90% correct. It means that most of the code, works correctly for cases specified in tests. If all tests pass, you can’t say you do not have bugs in your code.
Cyclomatic complexity – the lesser this number is,(usually) the better. Very high value of this may mean spaghetti code, but even if not, it means that the specified class / module or whatever part is being investigated, has many executions paths. More executions paths mean more complexity, more complexity makes for more difficult debugging. This measure is only a heuristic, as what is an acceptable complexity varies between projects.
Lines of code – this measure tells nothing at all about the complexity or quality of application. This number varies so much between different programming ecosystems, that taking it into account in anything besides just statistics is not going to be productive. Sure, a 2000 lines class in any programming language means trouble, but what really should be a “hard-stop” so to say? What number of lines indicates your class is too big? 100? 200? 500? This can’t be arbitrary solved.
Programming is not a reconstruction work. Creating a second piece of software is not like building a second house. New software projects has new requirements and needs new tools. You may say, that every house also has different requirements: number of rooms, placement of bathrooms. But when an architect creates a project of a house, he knows what has to be fitted, right from the beginning. The project may be altered in some ways after that, everyone has the right to change their mind. The case with software development is different: you don’t really know, what will be needed to fit during the course of work. You can plan ahead (hell, you should!), but there will always be some compromises, as you can’t prepare for everything that will happen in the future.
Nobody requests building a basement beneath their house, after the foundation has been laid. Nobody requests a car manufacturer to make an amphibian out of their freshly bought car. But such situations happen in software development. Engineering creates solutions, which serve their purposes well. Software development creates other types of solutions.