Summary

Introduced by Michael Feathers for the "first five principles" named by Robert C. Martin in the early 2000s that stands for five basic principles of object-oriented programming and design. The principles, when applied together, intend to make it more likely that a programmer will create a system that is easy to maintain and extend over time. The principles of SOLID are guidelines that can be applied while working on software to remove code smells by causing the programmer to refactor the software's source code until it is both legible and extensible.

The Single Responsibility Principle says that classes, modules, etc., should have one and only one reason to change. This helps to drive cohesion into a system and can be used as a measure of coupling as well.

Bad Example
public class Book
{
    public String getTitle()
    {
        return "A Great Book";
    }

    public String getAuthor()
    {
        return "John Doe";
    }

    // BAD! Class now has 2 reasons to change
    public void printCurrentPage()
    {
        System.out.println( "current page content" );
    }
}
                                        
Good Example
public class Book
{
    public String getTitle()
    {
        return "A Great Book";
    }

    public String getAuthor()
    {
        return "John Doe";
    }
}

// Printing is now handled by a separate class
public class HtmlPrinter
{
    public void printPage( int pageNo )
    {
        System.out.println( "Page No: " + pageNo );
    }
}
                                        

In the bad example, the class can change for two reasons, changes to the core model and also changes around printing A 'clean' approach is to make two smaller classes keeping the different concepts separate. This helps to isolate future changes and makes it really easy to follow for other Developers. Each class expresses its intent clearly.

The Open-Closed Principle indicates how a system can be extended by modifying the behavior of individual classes or modules, without having to modify the class or module itself. This helps you create well-encapsulated, highly cohesive systems.

The Liskov Substitution Principle also helps with encapsulation and cohesion. This principle says that you should not violate the intent or semantics of the abstraction that you are inheriting from or implementing.

The Interface Segregation Principle helps to make your system easy to understand and use. It says that you should not force a client to depend on an interface (API) that the client does not need. This helps you develop well-encapsulated, cohesive set of parts.

The Dependency Inversion Principle helps you to understand how to correctly bind your system together. It tells you to have your implementation detail depend on the higher-level policy abstractions, and not the other way around. This helps you to move toward a system that is coupled correctly, and directly influences that system’s encapsulation and cohesion.


Always code as if the guy who ends up maintaining your code
will be a violent psychopath who knows where you live

Martin Golding