Yagni, Kiss Me Solid! Top 13 Software Engineering Principles
Yagni, Kiss Me Solid! Top 13 Software Engineering Principles

Yagni, Kiss Me Solid! Top 13 Software Engineering Principles

Software engineering is an art.

You can read books about it, but you will never be good at it without practice and experience. Some people are good at it right from the start, some need coaching and training, and some will never get it. However, some principles help you move in the right direction.

Here is the list of the most essential software engineering principles:

  1. YAGNI
  2. KISS
  3. SOLID
  4. DRY
  5. Separation of concerns
  6. Avoid premature optimization
  7. Law of Demeter
  8. Big design upfront
  9. Single source of truth
  10. Principle of least astonishment
  11. Pareto principle
  12. Incremental development
  13. Command-query separation

A lot of developers don’t know how to start writing better code. Let’s fix that right now by exploring these fundamental software engineering principles.

YAGNI (You aren’t gonna need it)

When writing code, there are some things you can do that are just plain obvious and will make your life better. Other things are unnecessary and can hurt the program or cause problems. YAGNI is a software development principle that says that you should not add functionality until you need it.

In other words, when writing a program, start with what you need, not with what you might need. This can also be a valuable heuristic for eliminating features or requirements when planning, refactoring, or redesigning a software system.

KISS (Keep it simple, stupid)

If you’ve ever been asked to design software that does too many things, you’ve probably heard the KISS principle. This principle says that software should be “as simple as possible, but not simpler.” Of course, this principle is easily misinterpreted. Too many programmers mistake simple for easy or “finished.” It’s not. If a software project is simple, it does exactly what it needs to do, no more, no less.

Another way to interpret KISS is by “Keep it simple and straightforward”. This should encourage every software engineer to make his software application as easy to understand as possible.

SOLID principles

The SOLID principles of object-oriented programming are a set of design principles that emphasize the need to create and maintain a software architecture that is easy to change over time. First introduced by Robert C. Martin (Uncle Bob), the principles have become an essential aspect of many software developers’ daily routines.

SOLID is a mnemonic acronym that stands for five principles that describe how to create good object-oriented software. The principles are:

Single Responsibility Principle – This is the idea that a class should have one and only one reason to change. Each class needs to have a single responsibility or goal for its existence. For example, if you have a class that handles getting a user’s name, the class should not be responsible for sending an email within the application.

Open-Closed Principle – The Open-Closed Principle (OCP) is a principle of software design. It states that software entities (classes, modules, functions, etc.) should be open for extension but closed for modification. That means that such an entity can allow its behavior to be extended without modifying its source code.

Liskov Substitution Principle – Or LSP for short is used in object-oriented programming because it helps programmers write code and design objects to be easily reused in other programs. The LSP is all about substitutability, replacing any object of one type (the base type) with an object of another type (the derived type), and having the program still work. For more details on how the LSP can help you in the development process, read this article.

Interface Segregation Principle – The Interface Segregation Principle (ISP) is a model for building loosely coupled modules in object-oriented design. The principle states that a class should be forced to depend on methods it does not use. To implement the ISP, classes should be segregated into too many classes that are loosely coupled to one another. You can read this article if you want to see more explanations with code examples.

Dependency Inversion PrincipleDependency inversion is a technique that allows you to separate a class’s dependencies (code that it uses) from the class itself. This means you can make changes to the dependencies without having to change the class. For example, you have a class called Worker that depends on a class called Task. If Task changes, you may have to change the Worker to accommodate the change. But if you first create an interface called ITask that Task implements and Worker has a dependency on ITask, you don’t have to change Worker if Task changes.

DRY – Don’t repeat yourself

DRY – Don’t repeat yourself principle – is a single, all-encompassing principle in software development that advocates that, whenever possible, the human-readable source code of a program should not be duplicated.

According to this principle, each piece of knowledge should have one representation in the source code. This means that if you have a piece of source code relevant in more than one place, you need to write it only once.

In case you have duplications in the existing code, you can use various refactoring techniques to eliminate the duplication.

Separation of concerns

Software development has many underlying and interdependent activities which must be balanced. For instance, it is tough to build a good user interface without good software architecture, yet often developers have to concentrate on the UI first due to client pressure.

When this happens, it is too easy to leave behind a complex code with poor separation of concerns, leading to painful and expensive rework later. For this reason, the agile software development movement is built around a set of core values and principles centered on the idea that the best way to deliver quality software in a timely fashion is to treat each project as a series of small releases. Every small release provides business value to the user.

In software engineering, separation of concerns (SoC) is a design principle for separating a complex system into smaller components. Each component is responsible for only one module of the software product. The purpose of separation of concerns is to decrease complexity in software design, implementation, and testing.

Avoid premature optimization

As a programmer, you want to write code that’s easy to understand and maintain. Sometimes, though, you might be tempted to over-optimize—to write code that’s faster or uses less memory, or is otherwise more efficient in some way. In practice, it turns out that premature optimization is often a waste of time.

Before you go and optimize your code, you better know exactly what you’re doing. Most of the time, premature optimization is a code smell. This is why you should first take the time to define what you want to do and how you want to do it. If you are not sure about the exact problem you are trying to solve, it might be a good idea to step back a little and think about possible solutions and their pros and cons.

Law of Demeter

A good software design is easy to understand and read. This is true for both the code and the documentation. In the code, it is crucial to separate the methods by the levels of abstraction, not to repeat the same information in different methods, and use clear and meaningful variable names.

The Law of Demeter (LoD) is an object-oriented software design principle intended to express the idea that “A class should have only limited knowledge about the details of its dependencies.” This principle encourages decoupling by encouraging client classes to only request the methods or attributes needed to accomplish a task without exposing the inner workings of the object being used.

It is an additional recommendation to the interface segregation principle.

Big design upfront

Big design upfront is an important design principle used to guide the architecture and design of applications. In short, the concept is that the main design should be done before the coding starts.

This is important because the design reflects a clear picture of how the application will be built and how it will look before any code is written. This enables a team to discover and catch any complications and mistakes at the early stage of the project to reduce the costs and risks involved in the process of software development.

Single source of truth

A single source of truth is one unifying system of record that contains the authoritative data about an item or entity. It is a system that includes, in a single place, all the data relevant to a given item. Without a single source of truth, data can get duplicated – or worse, lost – and you may end up with multiple versions of the truth.

A single source of truth is not just a matter of convenience but critical for any system that aspires to be reliable, consistent, and trustworthy. Without a single source of truth, there is no way to keep information in sync, and everybody’s version of reality is different.

Principle of least astonishment

The Principle of least astonishment is a theory which states that the system you are designing should not surprise the user. Instead, create your system so that its behavior is consistent with the user’s prior knowledge. If the user is not surprised, they can feel a sense of control over the system, whereas surprises can leave them feeling frustrated or out of control.

If we have to press a button more than once to perform an action, we should be surprised (astonished). If we have to press the button only once, but it performs two activities, that’s a violation of the principle of least astonishment.

Pareto principle

The Pareto principle, also known as the 80/20 rule, states that 80% of the outcome results from 20% of the input. For example, 80% of a company’s sales come from 20% of its customers, and 80% of its profits are generated by 20% of its products or services.

This principle is commonly used in engineering to identify the most critical factors in a system. In the workplace, this is used to evaluate the most common reasons for a mistake or disaster and determine the most effective solutions. One example from computer programming: in a complex system, 20% of the system has 80% bugs. This is often the area in code that is very complex and hard to test with unit tests.

Incremental development

Incremental development says that you should make a small change in a program, compile it, then run it. You can see if the change was good or if it needs to be changed. You can do this as many times as you like. The process of making and testing changes like this is called an ‘incremental build’ or a ‘shortcut to failure’.

In terms of the software development process, incremental development is a software development technique that emphasizes the frequent, small addition of new functionality instead of a few giant leaps. This approach is intended to prevent project plans from becoming over-ambitious and ensure that time and money are spent wisely.

Command-query separation

What is Command-query separation? A simple definition would be that it is a programming design pattern in which we separate commands from queries. Commands tell objects to change their state, and queries retrieve the current state of an object.

This is important because it can help ensure that the code is easier to maintain and that you know what the outcome of a query is.

Conclusion

Software Engineering principles are one of the most important things in the industry today. Every single company, no matter how small or big relies on software today. Software is the backbone of today’s society. Many of the things we do every day are thanks to software. 

And by following top engineering principles, we can ensure that the backbone is stable and stays like that over a longer period of time.