# SOLID Principles (Series) [PART 1]

> If get to know something new by reading my articles, don't forget to endorse me on [LinkedIn](https://www.linkedin.com/in/rommansabbir/)

### What is **SOLID**?

**SOLID Principles** are an object-oriented approach that are applied to software structure design. **SOLID** principles were introduced by Robert C. Martin in his 2000 paper “**Design Principles and Design Patterns.**”

Why **Design Principles** matters?

* Encourage us to create more maintainable, understandable, and flexible software.
    
* As applications grow in size, we can reduce their complexity and save ourselves a lot of headaches.
    
* Software is modular, easy to understand, debug, and refactor.
    

### What **SOLID** stands for?

* \*\*S: \*\*Single Responsibility Principle.
    
* \*\*O: \*\*Open–Closed Principle.
    
* \*\*L: \*\*Liskov Substitution Principle.
    
* \*\*I: \*\*Interface Segregation Principle.
    
* \*\*D: \*\*Dependency Inversion Principle.
    

In this series, we'll start by defining each principle and then some examples to help us understand how and why we should use these principles in our code.

### SRP : Single Responsibility Principle

The **SRP** states that every `Class` must perform a single functionality. Implementation of multiple functionalities in a single class mashup the code and if any modification is required may affect the whole class. It precise the code and the code can be easily maintained.

### Example of SRP:

```plaintext
class User {
    fun getFirstName(): String {...}
    fun getLastName() : String {...}
    fun sendEmail(content : EmailContent) : Boolean {...}
    fun updatePrimayEmail(newEmail : String): Boolean {...}
    fun sendSMS(content : SMSContent) : Boolean {...}
}
```

We have a class called *User*, which has some responsibilites `getFirstName()`, `getLastName()`, `sendEmail(content : EmailContent)`, `updatePrimayEmail(newEmail : String)`, `sendSMS(content : SMSContent)`. Everything looks good and okay, right? Yes but only for this time only. Because it will lead to some challenges. We can not make the codes resuable. All responsiblites of this class is interconnected and that would be hard to fix any error if occurs. Also, as long as the code base grow, responsibilites added to the `Object`, makes it harder to refactor, maintain, or fixing any issue.

Let's talk about `Email` sending responsibilites. Currently, we have one `API` called `sendEmail(content:EmailContent)` which perform operation to send an email to a specific user. Lets say, `User` might have secondary email address. Also, we might need an `API` to re-send user verification email. If we add all of those `APIs` one by to the `User` object, object will get messy, un-maintainable, hard to refactor and if any issue occurs hard to fix.

So, how do we solve this problem? *By following* ***SRP***.

We can move all of the email related `APIs` to another service called `EmailService`. Now, `EmailService` is responsible to provide `APIs` for email related business logic.

```plaintext
class EmailService {
    fun sendEmail(user : User, content : EmailContent): Boolean {...}
    fun resendVerificationEmail(user: User, content : ResendEmailContent) : Boolean {...}
}
```

For, mobile SMS related `APIs` can be moved to `SMSService`

```plaintext
class SMSService{
    fun sendSMS(user : User, content : SMSContent): Boolean {...}
}
```

So, our final `User` class would be

```plaintext
class User {
    fun getFirstName(): String {...}
    fun getLastName() : String {...}
    fun updatePrimayEmail(newEmail : String): Boolean {...}
}
```

Now, responsiblites of our `User` object has been moved to respective services. Thus we can acheive ***SRP***. Keep in mind that, this is just an basic example.

In next part, we will talk about **Open–Closed Principle**.

That's it for today. Happy Coding...
