Skip to main content

SOLID Principles

Chapter Overview​

In this chapter you will learn:

  • What SOLID is
  • Why SOLID exists
  • Clean Architecture
  • Enterprise Design
  • Maintainable Code
  • The Five SOLID Principles
  • Real-world Examples
  • Laravel Architecture
  • PocketMine Examples
  • ZyroNetwork Examples
  • Best Practices
  • Interview Questions

Introduction

SOLID is one of the most important concepts in software engineering.

Modern frameworks like:

  • Laravel
  • Symfony
  • Spring Boot
  • ASP.NET
  • PocketMine-MP

all heavily follow SOLID principles.

Without SOLID:

Applications become:

❌ Hard to maintain
❌ Difficult to scale
❌ Full of bugs
❌ Difficult to test
❌ Difficult to understand

What is SOLID?

SOLID is an acronym:

LetterPrinciple
SSingle Responsibility Principle
OOpen Closed Principle
LLiskov Substitution Principle
IInterface Segregation Principle
DDependency Inversion Principle

Why SOLID Exists

Imagine:

ZyroNetwork Project

100 Classes
500 Files
20 Developers

Without standards:

Chaos.

SOLID helps create:

✅ Clean Architecture

✅ Scalable Applications

✅ Better Team Development


Visualization

SOLID
↓
Clean Code
↓
Maintainable Systems
↓
Enterprise Applications


S → Single Responsibility Principle (SRP)


Definition

A class should have only ONE reason to change.

or

One class = One responsibility.

Bad Example

class User {

public function save() {}

public function sendEmail() {}

public function generatePDF() {}

public function uploadAvatar() {}

}

Problems:

User class does EVERYTHING.

Why Bad?

If email changes:

User changes.

If PDF changes:

User changes.

One class becomes huge.


Better Example


User Model​

class User {

}

Email Service​

class EmailService {

}

PDF Service​

class PDFService {

}

Avatar Service​

class AvatarService {

}

Visualization

User
│
├── EmailService
├── PDFService
└── AvatarService

PocketMine Example

Bad:

Main.php

contains:

Commands
Forms
Database
Ranks
API
Events
Everything

Good:

Main
│
├── RankManager
├── DatabaseManager
├── FormManager
├── APIManager

Benefits

✅ Easier Maintenance

✅ Easier Testing

✅ Cleaner Architecture



O → Open Closed Principle (OCP)


Definition

Software should be:

OPEN for extension
CLOSED for modification

Meaning

You should be able to add new features without modifying existing code.


Bad Example

class Payment {

public function pay(
string $type
) {

if($type === "paypal") {

}

elseif($type === "stripe") {

}

}

}

Every new payment method requires modifying class.

Bad.


Good Example


Interface​

interface PaymentMethod {

public function pay();

}

PayPal​

class PaypalPayment
implements PaymentMethod {

}

Stripe​

class StripePayment
implements PaymentMethod {

}

Usage:

class PaymentService {

public function __construct(

PaymentMethod $method

) {

}

}

Now:

New methods can be added
without changing old code.

PocketMine Example

Commands.

Bad:

if($cmd === "ban")

Good:

BanCommand
KickCommand
MuteCommand

Each extends command system.



L → Liskov Substitution Principle (LSP)


Definition

Child classes should be replaceable
with parent classes
without breaking behavior.

Example


Parent​

class Bird {

public function fly() {

}

}

Child​

class Penguin
extends Bird {

}

Problem:

Penguins cannot fly.

Inheritance is wrong.


Better

class Bird {

}

class FlyingBird
extends Bird {

}

class Eagle
extends FlyingBird {

}

class Penguin
extends Bird {

}

Correct.


Why Important?

Bad inheritance creates bugs.


PocketMine Example

Bad:

Entity
↓
FlyingEntity
↓
Zombie

Zombie cannot fly.

Wrong hierarchy.



I → Interface Segregation Principle (ISP)


Definition

Clients should not depend
on methods they do not use.

Bad Example

interface Worker {

public function code();

public function cook();

}

Programmer:

class Developer
implements Worker {

}

Why should developer implement:

cook()

Bad design.


Better


Coding Interface​

interface Coder {

public function code();

}

Cooking Interface​

interface Cook {

public function cook();

}

Now classes implement only what they need.


Visualization

Bad:

Huge Interface

Good:

Small Interfaces

PocketMine Example

Bad:

PlayerInterface

with:

Chat
Movement
Permissions
Inventory
Networking
Forms

Huge.


Better:

PermissionInterface
InventoryInterface
ChatInterface


D → Dependency Inversion Principle (DIP)


Definition

Depend on abstractions,
not implementations.

Bad Example

class UserService {

private MysqlDatabase $db;

}

Service directly depends on MySQL.


Problems

❌ Cannot switch databases.

❌ Hard to test.


Good Example


Interface​

interface DatabaseInterface {

}

MySQL​

class MysqlDatabase
implements DatabaseInterface {

}

MongoDB​

class MongoDatabase
implements DatabaseInterface {

}

Service​

class UserService {

public function __construct(

DatabaseInterface $database

) {

}

}

Now:

Any database can be injected.

Amazing flexibility.


Visualization

Bad:

UserService
↓
MysqlDatabase

Good:

UserService
↓
DatabaseInterface
↓
MySQL
MongoDB
SQLite

Laravel Example

Laravel's entire container follows DIP.

Example:

UserRepositoryInterface

↓

UserRepository

PocketMine Example

Good architecture:

RankManager
↓
DatabaseInterface

Not:

RankManager
↓
MysqlProvider

ZyroNetwork Example


Architecture:

Main
│
├── DatabaseInterface
├── APIInterface
├── CacheInterface
└── LoggerInterface

Managers depend on interfaces.


Complete SOLID Example


Bad Architecture

Main.php

Contains:

Database
API
Commands
Forms
Ranks
Permissions
Network

5000 lines.

Nightmare.


Good Architecture

src/
│
├── API
├── Commands
├── Contracts
├── Database
├── Events
├── Forms
├── Managers
├── Models
├── Repositories
└── Services

Benefits of SOLID

✅ Easier Testing

✅ Better Team Development

✅ Easier Maintenance

✅ Better Scaling

✅ Cleaner Architecture

✅ Less Bugs


SOLID and Enterprise Applications

Every large company follows SOLID:

  • Google
  • Microsoft
  • Meta
  • Netflix
  • Amazon

because applications may contain:

100,000+
Classes

Without architecture:

Impossible.


Common Beginner Mistakes


God Classes​

Example:

Main.php

doing everything.


Huge Interfaces​

Interfaces with:

50 Methods

Terrible.


Wrong Inheritance​

Penguin extends Bird with fly method.


Hard Dependencies​

new Database()

everywhere.


Best Practices

✅ Keep classes small.

✅ Use interfaces.

✅ Depend on abstractions.

✅ Separate responsibilities.

✅ Prefer composition over inheritance.


SOLID Visualization

SOLID
│
├── SRP → One Responsibility
├── OCP → Extend without modification
├── LSP → Correct inheritance
├── ISP → Small interfaces
└── DIP → Depend on abstractions

Mini Project

Create:

Zyro Authentication System

Structure:

Contracts/
Services/
Repositories/
Managers/
Models/

Apply all SOLID principles.


Exercises


Exercise 1​

Refactor:

User

into multiple services.


Exercise 2​

Create:

DatabaseInterface

Exercise 3​

Create payment system using OCP.


Exercise 4​

Split huge interfaces.


Interview Questions


What does SOLID stand for?​

Single Responsibility

Open Closed

Liskov Substitution

Interface Segregation

Dependency Inversion


Which principle says one class should have one responsibility?​

SRP

Which principle says software should be open for extension?​

OCP

Which principle uses interfaces heavily?​

DIP

Which principle prevents huge interfaces?​

ISP

Which principle prevents bad inheritance?​

LSP

Summary

SOLID provides:

✅ Clean Code

✅ Scalable Applications

✅ Enterprise Architecture

✅ Better Team Development

✅ Easier Maintenance

✅ Better Testing

Modern frameworks and large applications rely heavily on SOLID principles.

Without SOLID, large projects quickly become difficult to manage.


References

https://en.wikipedia.org/wiki/SOLID

https://phptherightway.com/

https://martinfowler.com/

https://refactoring.guru/design-patterns


Next Chapter

➡ Design Patterns

➡ MVC Architecture

➡ Repository Pattern

➡ Service Container

➡ Event Driven Architecture