Boosting Laravel Quality with SOLID Principles: Best Practices and Examples (Part IV — I)

Niranjan Shrestha
3 min readApr 2, 2023

--

Interface Segregation Principle (ISP)

This principle in my opinion is the most simple to understand, but one of the most boring to implement. First, let’s understand how it works in theory and then we go to code.

💡 A client should only know the methods they are going to use and not those that they are not going to use.

We saw a lot of code on the previous principle, where we let the code more generic using OCP. But, something very important was missing. The return of the implement methods where we implemented the interfaces.

Basically, what this principle refers to is that we should not create classes with thousands of methods where it ends up being a huge file. Since we are generating a monster class, where most of the time we will only use some of its methods each time. And for that it refers to the need for interfaces, it is also important to understand that this helps a lot at the Single Responsibility Principle(SRP).

ISP takes place as Interface Segregation of specific things. Remember the first principle? Single Responsibility? Now we have the same point, but with Interfaces.

interface OAuthContract {
public function auth(string $code): bool;

public function getAuthenticatedUser(string $accessToken): array;

public function findUserById(string $accessToken, $userId): array;

public function followUser(string $accessToken, $userId): array;

public function unfollowUser(string $accessToken, $userId): array;
}

If you notice, we have two functions that in theory should be together.

It’s wrong? Not at all.

But when it comes to ISP, probably it’s wrong. But why exactly?

If you look again, you’ll see two thinks being done. One is essential, the other not so much.

Let’s build a scenario for that:

  • Our chatting software has a possibility to Sign In with Spotify, Twitch and Github;
  • But you can leave messages for when the user register, and will should be able to search for Users from Twitch and Github;
  • You’ll be able to follow these people social networks such Twitch or Github.

How we can segregate those interfaces?

interface OAuthBaseContract {
public function auth(string $code): bool;

public function getAuthenticatedUser(string $accessToken): array;
}
interface OAuthSocialContract {
public function findUserById(string $accessToken, $userId): array;

public function followUser(string $accessToken, $userId): array;

public function unfollowUser(string $accessToken, $userId): array;
}

We segregate the functions for each responsibility. OAuthBaseContract interface if only for authentication purpose and OAuthSocialContract is for social networking purposes.

Now, after segregation of interface we can implement those Interface/Contracts as:

class SpotifyService implements OAuthBaseContract {

public function auth(string $code): bool
{
return [];
}

public function getAuthenticatedUser(string $accessToken): array
{
return [];
}
}
class TwitchService implements OAuthBaseContract, OAuthSocialContract {

public function auth(string $code): array
{
return [];
}

public function getAuthenticatedUser(string $accessToken): array
{
return [];
}

public function findUserById(string $accessToken, $userId): array
{
return [];
}

public function followUser(string $accessToken, $userId): array
{
return [];
}

public function unfollowUser(string $accessToken, $userId): array
{
return [];
}
}
class GithubService implements OAuthBaseContract, OAuthSocialContract  {

public function auth(string $code): array
{
return [];
}

public function getAuthenticatedUser(string $accessToken): array
{
return [];
}

public function findUserById(string $accessToken, $userId): array
{
return [];
}

public function followUser(string $accessToken, $userId): array
{
return [];
}

public function unfollowUser(string $accessToken, $userId): array
{
return [];
}
}

We can see that SpotifyService needed only login authentication so we implemented OAuthBaseContract. If we hadn’t segregated previous interface we had to implement OAuthSocialContract methods too.

The idea is not to write unnecessary code and tell exactly which functions need to be implemented inside that class. How much more you segregate, more understandable will be your code and what is happening there.

<< Previous L — Liskov Substitution Principle(LSP)

>> Next D — Dependency Inversion Principle (DIP)

--

--