Introduction
Introduction
These notes are meant to reflect about how to organize the code, specially about how and when to structure the code in a procedural, object oriented or functional way. This is not a course on how to structure your code, but just an introduction to the ideas to have in mind when thinking about which approach to use to structure your code. I think that structuring the code is an art, a craft, that can only be adquired through practice and experience, especially with the experience of working with other good programmers, and it is a skill that is never completely mastered, but let’s hope that thinking about the motivations and tools involved one could develop this craft faster, and moreover, that one would learn about the importance of writting nicely structured code instead of an unmaintainalbe mess.
It is a common mistake, specially among beginers, to think that our aim when we write computer code is to create fast and memory efficient, very performant, programs. Of course we’d like our programs to run faster, but that’s not our only, or main, goal, otherwise every program would be writen in assembly, a language capable of squeezing out every bit of computing power out of our machines. However, few programmers write in assembly.
When one starts to code spends a lot of time thinking about how to implement the algorithms required to accomplish the task at hand, but as you gain experience in your programming carreer you focus your attention more and more in the structure of your code. Unstructured, spaghetti, code, could still be the option if you just need a 20 line script to solve a specific task, but for anything more complex than that you will realize that you need to think on the structure.
Performance is important, but programmers also have other aims like writting:
- a working product before the universe ends, and, even better, before their managers and clients run out of patience.
- realiable code that can be trusted.
- maintable code in which bugs are easily located and fixed, and new features can be easily added.
- portable programs that can be used in different hardwares and scenarios.
Readability and modularity are the two main ways to accomplish these goals.
We have to divide our programming projects into small modules. Here, by module, I just mean a program part, not a Python module, these modules can be packages, modules, classes, functions, data structures, etc. Big problems are daunting tasks and we usually solve them by dividing them into many small, or even trivial, tasks. Since the first days of coding, programmers have been thinking about how to accomplish this division into parts, in different ways of how to structure the code, in different programming paradigms.
Another advantage of creating small modules with clearly defined reponsabilities, like sorting a list of items or storing or loading data form disk, is that we can reuse them several times inside a project or even between projects. Programming, in practice, consists mainly in mixing previous ideas, in the form of libraries, packages or modules, to create the code that solve our current problem. Computer programs are akin to lego constructions. For programmers, it would be impossible to create even a relatively simple program from scratch, but this modularity allow them to create even complex software in little time. In fact, the only way to create a medium to large software project is to split its functionality in parts.
The functionality of these small parts is also easier to define precisely, to specify, and easier to check. Moreover, we could trust reused parts, that have already been tested in previous projects, than brand new ones, that are likely to include unknown bugs. Thus, programs created out of these parts will be more reliable. In fact, a fundamental good programming practice is to test the functionality of our code, and this is much easier to do if we divide our program into modules.
Medium and large programs can be only created and maintained by teams, they are not writen by lone programers. Thus, readability is a fundamental aspect. Code should be clear and easily understandable, readibility is paramount, and modularity is key in this regard. Remember the wisdom of the Zen of Python: “Readability counts”. If the software is relevant we will have to fix bugs and add functionality in the future. Even if we are working alone we have to take into account that our future self, in six months, won’t be able to understand the code unless is clear, and modularity facilitates this task.
So, we have to structure our code, but there are different ways of creating this structure. For instance, we could use a procedural, object oriented or functional approach. The aim of these notes is to help us reflect on the advantages and limitations of these approaches.
There are other texts that take a theoretical approach, but here we aim to be practical. One can think, for instance abouth functional programming, in a very theoretical way, but our notes on the functional approach won’t be that. I write code in Python, a multiparadigm language. I can choose to use a procedural, object oriented or functional approach, and I can mix these ways of structuring the code in the same project. So, which is the best way to do it? We won’t be able to provide absolute rules to answer this question, nobody does, but let’s hope that these lines help us to think about it in a more productive way.
If you have just started coding, I guess that all this ideas might sound very abstract, but, maybe, reading about these paradigms, these approaches, might, at least, convince you that you have to care about the structure of your code, and that, with time, you’ll have to improve on this skill.
Licence
This content is released under a Creative Commons BY licence.