Previously, I was asked to explain the Dependency Inversion principle in an interview — I had briefly covered SOLID, though it wasn’t concrete in my memory.

The last few days I have been scraping the internet looking at examples for each of the principles. I wanted to make the examples as high level as possible so the concepts are what stand out, not the syntax.

According to wikipedia:

“SOLID is a mnemonic acronym for five design principles intended to make software designs more understandable, flexible and maintainable.”

Ideally, we want our software to be readable, able to handle change efficiently, and testable.

Mastering the SOLID principles will no-doubt make you a better developer.

Let’s start.

S — Single Responsibility Principle

“Each class and module in a program should focus on a single task”

Real World Example

Vacuum Cleaner

Clean carpets, tiles, has heaps of nozzles and attachments.

However, at its core — its main responsibility is to suck in dirt/dust etc and store it in its container that can then be thrown out.

— its main is to suck in dirt/dust etc and store it in its container that can then be thrown out. If we had a vacuum that cleans windows, it may work and that’s all fine and good. Though as time goes by, it may increase maintenance costs and inevitably break down.

Code Example — Invoice

public class Invoice { private String customer;

private String state;

private int total; public Invoice(String customer, String state, int total) {

this.customer = customer;

this.state = state;

this.total = total;

} //Getters & Setters public String getDetails() {

return this.getCustomer() + ", " + this.getTotal();

} public void emailInvoice() {

System.out.println("Sending email...");

System.out.println(this.details());

} public double determineTax() {

switch(this.state) {

case "VIC":

return 0.3;

case "NSW":

return 0.5;

default:

return;

}

} }

Here we have an Invoice class that seems to be relatively straightforward. The class:

Returns details about the invoice

Calculates sales tax

Emails the invoice with its details

When we run the code everything works fine.

Rule of Thumb: No ANDs allowed

Let’s break down what our invoice class does:

“The invoice class returns invoice details AND calculates sales tax AND emails the invoice.”

It’s doing too much. When refactoring, treat the behaviour between the ANDs as their own class.

Refactoring

We’ll be creating seperate classes:

Mailer — handles the emailing

— handles the emailing Sales Tax — handles the sales tax calculation

— handles the sales tax calculation Invoice — handles the invoice info

Invoice Class

public class Invoice { private String customer;

private int total;



public Invoice(String customer, int total) {

this.customer = customer;

this.total = total;

}



//Getters & Setters



public String getDetails() {

return this.getCustomer() + ", " this.getTotal();

}

}

Notice the removal of state attribute. As the Invoice class is no longer taking responsibility of sales tax, it is no longer necessary.

Sales Tax Class

public class Sales Tax { private String state;



public Sales Tax(String state) {

this.state = state;

}



//Getters & Setters



public double determineTax() {

switch(this.state) {

case "VIC":

return 0.3;

case "NSW":

return 0.5;

default:

return;

}

}

}

The Tax class should be decoupled from the Invoice class, as it may need to be used in other parts of the application. Keeping the sales tax inside the invoice class means we need to create an Invoice class to access the sales tax.

This violates the SRP principle.

Mailer Class

public class Mailer {



public Mailer(){}



public static void sendEmail(String content) {

System.out.println("Sending email...");

System.out.println(content);

}

}

The Mailer class takes complete responsibility of emailing customers.

Want to email an invoice? Input the invoice details.

Want to email them a newsletter? Input the newsletter into the content parameter.

Running the Application

public static void main(String[] args) { //Create a new invoice Invoice invoice = new Invoice("John Doe", 100); //Create a tax object Sales Tax tax = new Sales Tax("VIC");

tax.determineTax(); //returns 0.3 //Print out the details String details = invoice.getDetails();

System.out.println(details); //Outputs; "John Doe, 100" //Let's email the invoice Mailer.sendEmail(details);



}

Wrapping Up

So why is this type of design pattern important?