SOLID vs OOP in Ruby: Are We Just Repackaging the Same Ideas?
June 24, 2025
In a recent round of technical interviews, I was asked about the SOLID principles. Like many Ruby developers, I’ve spent years applying object-oriented concepts in practice — even before SOLID was something people talked about regularly.
As I dug deeper into the acronym, something became clear:
Many of the “new” principles in SOLID are just classic object-oriented programming concepts — rephrased, renamed, and organized under a new label.
So in this article, I’d like to explore how SOLID overlaps with traditional OOP theory , using Ruby examples , and why that matters.
Classic OOP Concepts in Ruby
Ruby is a truly object-oriented language. It’s expressive, flexible, and built on OOP principles. Here are the core ones:
1. Encapsulation
Hide internal details behind a public interface.
class BankAccount
def initialize(balance)
@balance = balance
end
def deposit(amount)
@balance += amount
end
private
def log_transaction
# internal logging
end
end
2. Inheritance
Use shared behavior across subclasses.
class Animal
def speak
"..."
end
end
class Dog < Animal
def speak
"Woof"
end
end
3. Polymorphism
Different classes respond to the same method call.
def make_sound(animal)
animal.speak
end
make_sound(Dog.new) # => "Woof"
make_sound(Cat.new) # => "Meow"
Enter SOLID Principles
Let’s walk through each SOLID principle and map it directly to the OOP concept it depends on — with Ruby examples.
S — Single Responsibility Principle (SRP)
A class should have one and only one reason to change.
This is an extension of encapsulation — focus each class on one thing.
#  Violates SRP
class Report
def generate
# generate logic
end
def send_email
# mail logic
end
end
#  Follows SRP
class ReportGenerator
def generate
# logic
end
end
class ReportMailer
def send_email
# logic
end
end
O — Open/Closed Principle (OCP)
Software entities should be open for extension, but closed for modification.
Built on polymorphism and inheritance.
# Without OCP: adding a new format requires editing this method
class Invoice
def export(format)
if format == :pdf
# ...
elsif format == :csv
# ...
end
end
end
# With OCP: extend via polymorphism
class InvoiceExporter
def initialize(strategy)
@strategy = strategy
end
def export(invoice)
@strategy.export(invoice)
end
end
class PdfExporter
def export(invoice)
# PDF logic
end
end
class CsvExporter
def export(invoice)
# CSV logic
end
end
L — Liskov Substitution Principle (LSP)
Subtypes must be substitutable for their base types.
This is about safe inheritance. Ruby makes it easy to break this with monkey-patching, so caution is key.
class Bird
def fly
"I'm flying"
end
end
class Penguin < Bird
def fly
raise "I can't fly"
end
end
#  Violates LSP — a Penguin is not a substitutable Bird
#  Use composition instead
class Bird
end
class FlyingBird < Bird
def fly
"I'm flying"
end
end
class Penguin < Bird
# No fly method — safe
end
I — Interface Segregation Principle (ISP)
Clients should not be forced to depend on methods they do not use.
Ruby doesn’t have interfaces, but small modules help.
#  One big interface
module Worker
def work; end
def eat; end
def sleep; end
end
#  Split interfaces
module Workable
def work; end
end
module Eatable
def eat; end
end
D — Dependency Inversion Principle (DIP)
Depend on abstractions, not concretions.
In Ruby, this often means injecting dependencies , instead of hard-coding them.
#  Violates DIP
class Notifier
def initialize
@mailer = GmailMailer.new
end
end
#  Follows DIP
class Notifier
def initialize(mailer)
@mailer = mailer
end
end
Notifier.new(SendGridMailer.new)
Final Thoughts: Just Another Name?
To me, SOLID doesn’t introduce brand-new ideas — it just repackages and refines OOP best practices. That’s not a bad thing. But in a world full of acronyms, patterns, and buzzwords, it’s easy to get lost.
Sometimes, going back to the roots of OOP is enough.
If you know how to model objects well, use composition, write clear responsibilities, and test your code — you’re already doing most of what SOLID asks.
What’s Your Take?
- Do you use SOLID when writing Ruby?
- Do you think these principles add value, or just complexity?
Let’s chat in the comments — I’d love to hear your experience with this balance of theory and practice.
Top comments (0)