KISS (Keep It Simple, Stupid)
The principle of simplicity states that codes should be as simple as possible without a complicated structure, otherwise debugging and maintenance might be more difficult. Moreover, another programmer will have a harder time understanding the code logic, which will entail more time and effort. Do you want to add that complexity? When coding your next big project, make sure you write simple and easily comprehensible code.
- It’s best if your methods are small, not exceeding 40-50 lines.
- All the crucial/critical methods should have a commented doc for better understanding for other dev.
- Methods should only address one problem at a time.
- Your project has a lot of conditions, right? Break up the codes into smaller blocks as you go.
- If possible, use simple constructions that solve the problem without a lot of branching, deep nesting, or complex class structures.
You, along with co-workers, can identify bugs faster with Always Keep It Simple, Stupid (KISS). The principle also makes it easier to modify and improve code. Remember what Edsger W. Dijkstra said: “Simplicity is a prerequisite for reliability”.
DRY (Don’t Repeat Yourself)
The principle of DRY states that we shouldn’t repeat the same thing too many times in too many places. In software systems, it aims to reduce repetitive code and effort. Developers unknowingly re-write code repeatedly. When writing your code, don’t copy-paste the same code repeatedly. If you don’t, then you’ll need to keep them in sync; any change in code at one place will need to be done at other places. It will take extra time, effort, and attention (which isn’t always easy).
- Make sure not only that your code is error-free, but that it is free of duplicate lines.
- If a piece of code appears more than twice in the codebase, it should be moved to a separate function.
- You should create a separate method even if you find that it is repeated a second time.
- As a bonus, automate any manual processes you can in order to keep the code lean.
These steps will facilitate the reusability of software code, preventing it from having to be repeated. As a result, the code becomes more reusable, more extensible, and less buggy.
YAGNI (You Aren’t Gonna Need It)
In accordance with this principle, programmers should not include functionality unless it is absolutely necessary. It states that you shouldn’t introduce things to solve future problems that don’t exist yet. In most cases, programmers try to implement all the functionality at once, right from the beginning. Eventually, most of these functionalities are rendered useless. Additionally, the absence of YAGNI may lead to disorganized code and very extensive rework.
- It’s always a good idea to add only a few methods to a class at the beginning. You should not add dead code to the project.
- Once your project begins taking shape and new needs arise, you can add more functionality. Consequently, you’ll get lean software development.
- As a result, you save unnecessary time, effort, and costs associated with trying to understand or debug the code.
It is recommended to implement only the essential features first, and then, as necessary, expand them. YAGNI also avoids complexity, specifically that which comes from adding features that may be necessary for the future.
BDUF (Big Design Upfront)
According to this principle, a developer should design the project first, create the flow of the diagram, and then implement it later. Before developing functionality, we should first think about the architecture and design of the whole system to the smallest details, and then follow the steps outlined in our plan to implement it.
This helps uncover issues at the requirements stage and resolve them quickly. It is possible, however, that software requirements may change during the project’s life cycle and such changes to software requirements may result in difficulties or may even render the design obsolete. The best way to handle this would be by designing the architecture first, then dividing the requirements into stages according to their priority. Develop from the highest priority stage to the lowest during the development process. Prior to coding, implement the BDUF principle at each step.
SOLID is an acronym for a collection of object-oriented design principles. Each letter in the”SOLID” stands for one of the following principles:
S – SRP (Single Responsibility Principle): According to the Single Responsibility Principle, a class, function, module, or service must have only one reason to change, i.e., it must have only one responsibility. Yet why is this so important?
- When you write classes or functions that are dedicated to a single functionality, it becomes easier to understand, maintain, and modify your code.
- If you want to modify the functionality of the system, you would know the exact DRY location where you have to modify the code.
- It makes the code more organized and readable. It also makes reusing the code easier.
O – OCP (Open Closed Principle): In software development, we work in phases. As a team, we implement a bunch of functionalities, test them, and then deliver them to the users. We then move on to implementing the next set of functionalities. When it comes to developing new functionality, the last thing we want to do is to change the existing functionality, which has been tested and is working. Therefore, we try to add new functionality on top of existing ones.
This idea is facilitated by the Open-Closed principle. According to it, our functions, classes, and modules should be designed in such a way that they’re open for extension, but closed for modification.
- Open for Extension: New functionality can be added to classes and modules without breaking the existing code. Composition and inheritance can be used to accomplish this.
- Closed for Modification: It’s ideal not to make changes that break current functionality, as doing so would require refactoring a lot of existing code and writing several tests to ensure the changes work.
L – LSP (Liskov Substitution Principle): According to the Liskov Substitution Principle, all child/derived classes should be replaceable for their parent/base classes without affecting or breaking the program’s correctness. Thus, objects in your subclass (derived/child class) should behave similarly to objects in your superclass (parent/base class). Therefore, you should use inheritance carefully in your projects. While inheritance can be beneficial, it is advisable to use it moderately and contextually. Before you can perform inheritance, you have to consider the postconditions and preconditions of the class.
I – ISP (Interface Segregation Principle): According to the Interface Segregation Principle, clients shouldn’t be forced to depend or rely on methods that they don’t use. How can this be achieved? Simple: make your interfaces short or small and focused. An interface with a lot of behaviors is hard to maintain and evolve. Therefore, Separate large interfaces into smaller ones, each focused on a specific set of functions, so that choose to depend or rely only on the functionalities that they require
D – DIP (Dependency Inversion Principle): This Principle seeks to eliminate tight coupling between software modules. According to this principle, high-level modules should not depend on lower-level modules, but rather on their abstractions. We can break it down into two parts:
- A high-level module must be independent of a low-level module. Both should rely on abstractions
- The abstraction should be independent of the details, while the details should be dependent upon the abstractions.
Why do we follow this principle? The reason is that abstractions are pretty stable. As a result, you can easily modify the behavior of your open-source or closed-source code. Therefore, you can improve its future evolution.
Avoid Premature Optimization
Premature optimization was said to be the root of all evil in programming by Donald Knuth. As a whole, we agree that optimization (improving the quality and efficiency of code) increases development speed while reducing resource use. It may, however, be detrimental if done too early.
- A major reason for this is that the development of the optimized code takes more time and effort.
- Moreover, when the most optimal approach is implemented, software requirements may change. When this happens, your program ends up in the trash or becomes difficult to change.
- Additionally, regression tests are often needed to confirm the correctness of the whole system.
It is, therefore, best to use a simple approach at first, though it might not be optimal. Later on, after estimating how much this approach slows down the application, you might switch to a faster or less resource-intensive algorithm.
Measure Twice and Cut Once
The golden rule in engineering is to measure twice and cut once. In essence, this principle says you must plan and prepare thoroughly and carefully before you take an action. Whenever you are creating a new system, be sure it is useful, desirable, easily accessible, and credible. The requirement stage of the development life cycle can cause more than 50 percent of coding issues if not done correctly. Thus, you should adopt a systematic approach to the coding process.
- Verify that you haven’t omitted or added too many requirements in your code.
- Develop blueprints that will allow high-quality coding to be achieved throughout the process.
- Test your project from the start to ensure it’s working correctly.
Principle of Least Astonishment
It is also called the Principle of Least Surprise, and it has been around for a long time. Ideally, a feature should not have a high-astonishment factor, according to the principle of least astonishment. It means that you should write code that is intuitive and obvious so that it doesn’t surprise others when they review it. Components of your system should behave as expected by end-users. Otherwise, users are unlikely to use features or structures that astonish them, surprise them, or confuse them. Making a method named making_Patties but resulting in tomato objects instead would be a total surprise and clearly bad, no matter what its name may be. The naming convention for methods, classes, variables, parameters is very much required for software maintenance.
Software products are what you make for people to use. Therefore, you can reap a great deal by creating user-friendly features. Try to comply with human mental models, experiences, and expectations. Remember to grab the user’s attention as quickly as you can, as the average user’s attention span has declined.