What is Software Engineering?
I believe in the power of analogies as a way to conceptualize and understand abstract problems. There is an abundance of metaphors around software development. Quoting Steve McConnell in Code Complete 2, software development is considered to be "a science (David Gries, 1981), an art (Donald Knuth, 1998), a game (Alistair Cockburn, 2002), similar to driving a car (P. J. Plauger and Kent Beck, 1993), and even making your way through a tar pit surrounded by dinosaurs (Frederick P. Brooks, 1995)."
Undoubtedly, the most famous & repeated analogy is to consider software development to be analogous to constructing a building. In order to make a building, one calls an architect to draw up the blueprints, which are handed over to a builder who then constructs that building according to the specifications in these blueprints, in accordance with professional standards.
I have heard (and used) this analogy in the past, but I have come to realize how it may convey a partial understanding of what software engineering really is. The main reason is that buildings have a much higher fault tolerance than software. More often than not, placing a brick or torque slightly off will not cause the building to collapse. On the other hand, the slightest buffer overflow or a single null pointer can cause any given system to crash or be exploited. I see countless walls that don't line up perfectly, pipes that don't quite connect correctly, or windows that don't close perfectly. Buildings aren't built flawlessly, and they don't have to. Many errors are easily painted over. Software engineering is incredibly more complex than building sky-scrappers, and small errors are prone to be magnified. Microsoft's Windows operating system, is likely made of around 50 million lines of code, while the Empire State building has 100,000 rivets and 10 million bricks, many of which having been built in a quite standardized way.
This being said, it took a while for me to find a proper analogy that I would be comfortable using, and to which I could relate to. This was until I came across Andy Hunt's book, The Pragmatic Programmer (2019), who considers software development to be less like building construction, and more like gardening.
Sure there's always some planing to be done: a landscapist will perform some on-site analyses and land planning, while a few other experts will prepare the soil, decide the types of plants, where and how to plant them according to many parameters... Similarly, software engineers will come up with the specifications and requirements, while others will write the well-designed code that will eventually grow to become the overall system.
However, once the seeds blossom, the garden doesn't quite come up the way you imagined it: some plants are smaller, some are bigger, or less leafy than you hoped, the colors are nothing like you imagined, they don't look good next to each other, and some may even die soon afterwards. Quite the same way, programmers must face development bugs and strive towards getting rid of them, make tests to avoid them, make some adjustments; all this for the end user's enjoyment.
Just like there is no such thing as a low-maintenance garden, there is no such thing as low-maintenance software. Both need to be maintained -- in a very different way than buildings. Software and gardening maintenance are organic by nature, their shape will change over time, and both imply regular interactions. Farmers and developers both face priorities, constraints & variables, which they do their best to control and make do. Software and gardens grow, more or less visibly to the public: sometimes, focus may be on pruning, for better robustness/structure, and sometimes it's flower/feature season. Both the developer & the gardener care about their code/flowers, continuously getting rid without second thoughts of any weeds and bugs, stuff that are sin't needed or unwanted, allowing room for improvements later on. Both must pay close attention to resources, as too much or too little may be counterproductive.
The matter of fact is, software is nothing mechanical, it is not static, and it is not concrete. It is not just built, and that's it. Software is soft, and alive in many ways.
This reflection may not be new to a software developer, but a significant amount of non-technical people may not realize this.