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