Object-Oriented Design

SOLID Principles Cheat Sheet

Converted into the same previous HTML reference format, with navigation, principle-by-principle explanations, BAD/GOOD examples, code-smell indicators, benefits, and original PDF pages preserved for reference.

Source-based conversion: The supplied five-page cheat sheet covers Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation and Dependency Inversion principles. The original source organizes each principle into Meaning, Example, How to recognize code smell?, and Benefits. fileciteturn3file0L30-L34
1

Single Responsibility Principle

1. Meaning

A class should have only one responsibility, which means the class should be highly cohesive and implement strongly related logic.

2. Example — BAD

PlaceOrder
class PlaceOrder
  def initialize(product)
    @product = product
  end

  def run
    # 1. Stock availability
    # 2. Payment process
    # 3. Shipment process
  end
end

Example — GOOD

Improved design
class PlaceOrder
  def initialize(product)
    @product = product
  end

  def run
    StockAvailability.new(@product).run
    ProductPayment.new(@product).run
    ProductShipment.new(@product).run
  end
end

3. How to recognize code smell?

  • More than one contextually separated piece of code within a single class
  • Large setup in tests; TDD can help detect SRP violations

4. Benefits

  • Separated classes responsible for a use case can be reused elsewhere
  • Separated classes can be tested independently
2

Open/Closed Principle

1. Meaning

A class should be open for extension and closed for modification. Extend behavior without modifying the existing implementation.

2. Example — BAD

Logger
class Logger
  def initialize(logging_form)
    @logging_form = logging_form
  end

  def log(message)
    puts message if @logging_form == "console"
    File.write("logs.txt", message) if @logging_form == "file"
  end
end

Example — GOOD

Improved design
class EventTracker
  def initialize(logger: ConsoleLogger.new)
    @logger = logger
  end

  def log(message)
    @logger.log(message)
  end
end

class ConsoleLogger
  def log(message)
    puts message
  end
end

class FileLogger
  def log(message)
    File.write("logs.txt", message)
  end
end

3. How to recognize code smell?

  • Class X directly references class Y from within its code base
  • Complex if-else or switch statements

4. Benefits

  • Functionality can be extended with a separate class without changing class X
  • Code is loosely coupled
  • Injected class Y can be easily mocked in tests
3

Liskov Substitution Principle

1. Meaning

Derived classes should not change the behavior of the base class. If Y is a subclass of X, instances referencing X should be able to reference Y as well.

2. Example — BAD

Rectangle / Square
class Rectangle
  def initialize(width, height)
    @width, @height = width, height
  end

  def set_width(width)
    @width = width
  end

  def set_height(height)
    @height = height
  end
end

class Square < Rectangle
  # LSP violation: inherited class
  # changes parent behavior
end

Example — GOOD

Improved design
class Rectangle
  def initialize(width, height)
    @width, @height = width, height
  end
end

# Prefer a shared abstraction whose contract
# both shapes can honor without changing
# inherited behavior unexpectedly.

3. How to recognize code smell?

  • Modification of inherited behavior in a subclass
  • Exceptions raised in overridden inherited methods
  • A type looks substitutable but needs special behavior to work

4. Benefits

  • Avoid unexpected and incorrect results
  • Clear distinction between shared inherited interface and extended functionality
4

Interface Segregation Principle

1. Meaning

Clients should not depend on interfaces or methods that they do not use.

2. Example — BAD

Car / Driver / Mechanic
class Car
  def open
  end

  def start_engine
  end

  def change_engine
  end
end

class Drive
  def take_a_ride(car)
    car.open
    car.start_engine
  end
end

class Mechanic
  def repair(car)
    car.open
    car.change_engine
  end
end

Example — GOOD

Improved design
# Split the large interface into
# smaller client-specific interfaces.

class DriverCar
  def open
  end

  def start_engine
  end
end

class MechanicCar
  def open
  end

  def change_engine
  end
end

3. How to recognize code smell?

  • One fat interface is implemented by many classes, while none use 100% of its methods
  • The fat interface should be split into smaller interfaces suitable for client needs

4. Benefits

  • Highly cohesive code
  • Avoids coupling between classes using one fat interface
  • Clear separation of business logic by grouping responsibilities into separate interfaces
5

Dependency Inversion Principle

1. Meaning

High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details; details should depend on abstractions.

2. Example — BAD

EventTracker / ConsoleLogger
class EventTracker
  def initialize
    # Low-level class is created
    # directly inside high-level class
    @logger = ConsoleLogger.new
  end

  def log(message)
    @logger.log(message)
  end
end

Example — GOOD

Improved design
class EventTracker
  def initialize(logger: ConsoleLogger.new)
    # Dependency injection
    # makes the high-level class
    # independent of a concrete logger
    @logger = logger
  end

  def log(message)
    @logger.log(message)
  end
end

3. How to recognize code smell?

  • Instantiation of low-level modules in high-level ones
  • Direct calls to low-level module/class methods

4. Benefits

  • Increases reusability of higher-level modules by making them independent of lower-level modules
  • Injected classes can be easily mocked in tests

Original PDF Pages

The original five pages are preserved below so the source layout and examples remain available alongside the converted HTML content.

Original SOLID Cheat Sheet — Page 1 Original SOLID Cheat Sheet page 1
Original SOLID Cheat Sheet — Page 2 Original SOLID Cheat Sheet page 2
Original SOLID Cheat Sheet — Page 3 Original SOLID Cheat Sheet page 3
Original SOLID Cheat Sheet — Page 4 Original SOLID Cheat Sheet page 4
Original SOLID Cheat Sheet — Page 5 Original SOLID Cheat Sheet page 5