Software Development Principles — it is a number of specific rules and recommendations, which engineers need to be followed during program implementation if they want to write beautiful, understandable and maintainable code. There is no magic wand, by which you can transform a mixture of variables, classes and functions into the ideal code, but there are some tips and hints, which can help the engineer to determine if he doing things right. Let's look at this base recommendations. Some of these principles are Python-specific, but most are not.
I think this is the most important principle at all. If you learn just one principle from this post - it should be this. We, developers/devops/architects/managers people struggle from lack of attention, from stupid mistakes and typos. I think this principle in terms of engineering means quality, confidence in your code/process/system/etc. But this confidence cannot go from the code itself, it should go from tests.
Don’t Repeat Yourself (DRY)
It's pretty simple, but very useful principle, which says that repeating the same code in different places is a bad idea. This is primarily due to the need to further maintain and modify the code. If some code snippet duplicates in several places within the program then there is a high probability of two disastrous situations:
- If necessary make even small corrections into source code, you need to change the same code in several places where it is using which will require additional time and effort(it is not easy sometimes - see Miller's law)
- From the first item follows the second, you or another developer may accidentally miss one of the fixes and face subsequent errors in the application.
In this regard, there is a recommendation, if any code is found in the listing more than two times, then it should be placed in a separate method. This is a general recommendation, in fact, you need to think about creating a separate method, even if you meet the repetition a second time.
It is a very common idea which came into programming from philosophy. The principle got its name from english monk William of Ockham. This principle says: «Entities are not to be multiplied without necessity». In IT this principle is interpreted as follows - no need to create extra entities without the need for them. So, you always need to think first about the benefits of adding one more method/class/tool/process/etc. After all, if you add one more method/class/tool/process/etc and don't get any benefits but increasing complexity then what's the point?
Keep It Simple Stupid (KISS)
It is a very similar principle with the one above but this one has slightly different meaning. This principle says that code should be simple, without any complicated structures if possible, otherwise it will overcomplicate debugging and maintenance of the code. In addition, it will be much more difficult for another programmer to understand the intricacies and complex branches of the listing, which will also require additional time and effort. Therefore, always try to use simple and logical constructions without deep nesting, by doing this you will simplify life for yourself and for your colleagues because complexity breeds bugs. Remember what Pieter Hintjens said: "Simplicity is always better than functionality."
You Aren’t Gonna Need It (YAGNI)
A problem which a lot of programmers suffer. The desire to implement at once all necessary (and sometimes even unnecessary) functionality from the very beginning of the development process. That is when the developer from the very beginning adds all possible methods to the class and implements them, while in the future it may even never use them. Therefore, according to this recommendation, implement only what you need in the first place, and in the future, if necessary, increase the functionality. So you will save efforts, time and nerves on debugging code that is not really needed.
Before starting to develop functionality it is necessary to think first about application architecture and design the entire information system up to fairly small details, and only then proceed to implement according to a previously prepared plan. The principle has the right to exist, but recently there is quite a lot of his criticism. This is primarily due to the obsolescence of the plan during the design and development. In this connection, you still have to make subsequent changes. But it also has irrefutable advantages, with the proper design you can significantly reduce the cost of further debugging and fixing bugs. In addition, such information systems are usually more concise and architecturally correct.
"Premature optimization is the root of all evil (or at least most of it) in programming" - Donald Knuth
Optimization is a very right and necessary process that allows you to speed up the work of the program, as well as reduce the consumption of system resources. But everything has its time. If optimization is carried out in the early stages of development, then it can do more harm than good. This is primarily due to the fact that the development of optimized code requires more time and effort of the developer and it may be more complex. In this case, quite often it is necessary to first verify the correctness of the chosen development approach. Therefore, at first, it is more profitable to use simple, but not the most optimal solutions. And in the future, assessing how much this application slows down the work of the application, perform the change to a faster or less resource-intensive algorithm. In addition, for the time while you initially implement the most optimal algorithm, the requirements may change and the code will go to the garbage. So no need to spend time on premature optimization.
This principle means that your code should be intuitive and obvious, and not surprise another developer during code review. Example, if the method called "make cookies", but as a result, you get a potato than this code is bad(obviously).
“SOLID” is actually a group of object-oriented design principles used by individual developers when writing code. Each letter in “SOLID” represents one of the principles, which are:
- Single responsibility states that every module or class should have responsibility over a single part of the functionality provided by the software and that responsibility should be entirely encapsulated by the class;
- Open-closed states that software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification;
- Liskov substitution states that the inhereted class should complement, not replace, the behaviour of the base class;
- Interface segregation states that no client should be forced to depend on methods it does not use;
- Dependency inversion says that programmer should work at the interface level and not at the implementation level.
When applied together, these principles help a developer create code that is easy to maintain and extend over time
The main idea of this principle is to divide the areas of responsibilities between classes in your code and encapsulation of logic inside the class, method or structure. From this principle we can highlight several recommendations:
- Classes or entities should be independent
- Need to try to reduce the number of connections between different classes(aka coupling)
- Related classes should be in the same module/package/directory (aka cohesion)
By following this principle, the application becomes more flexible, understandable and maintainable.
Fellow developers let’s be engineers! Let’s think about design and build robust and well-implemented systems, rather than growing organic monsters. Listed principles are highly correlated and connected in there essence. Of course I didn't create them, but a small reminder does not hurt, at least my memory is definitely not perfect.
Thank you for reading!
Any questions? Leave your comment below to start fantastic discussions!