Про принцип незалежних об'єктів (Dependency Inversion Principle - DIP)

Принцип незалежних об’єктів (Dependency Inversion Principle - DIP) є одним з п’яти принципів SOLID і визначає, що модулі верхнього рівня не повинні залежати від модулів нижчого рівня. Обидва типи модулів повинні залежати від абстракцій. Також, деталі не повинні залежати від абстракцій, але абстракції повинні залежати від деталей.

Основні ідеї DIP.

Залежність від абстракцій - класи верхнього рівня повинні залежати від абстракцій (інтерфейсів чи абстрактних класів), а не від конкретних реалізацій (конкретних класів) нижчого рівня.
Введення абстракцій - абстракції повинні визначати важливі операції, а деталі мають залежати від цих абстракцій, а не навпаки.
Інверсія залежностей - модулі верхнього рівня не повинні контролювати деталі нижчого рівня; навпаки, обидва рівні повинні залежати від абстракцій.

В Ruby, принцип незалежних об’єктів (DIP) також може бути демонстрований за допомогою модулів та класів.

# Абстракція (модуль)
module SwitchableDevice
  def turn_on
    raise NotImplementedError, 'Subclasses must implement the turn_on method'
  end

  def turn_off
    raise NotImplementedError, 'Subclasses must implement the turn_off method'
  end
end

# Деталі нижчого рівня
class LightBulb
  include SwitchableDevice

  def turn_on
    puts 'LightBulb: Bulb turned on...'
  end

  def turn_off
    puts 'LightBulb: Bulb turned off...'
  end
end

class Fan
  include SwitchableDevice

  def turn_on
    puts 'Fan: Fan turned on...'
  end

  def turn_off
    puts 'Fan: Fan turned off...'
  end
end

# Клас верхнього рівня, який залежить від абстракції
class Switch
  def initialize(device)
    @device = device
  end

  def turn_on
    @device.turn_on
  end

  def turn_off
    @device.turn_off
  end
end

# Використання принципу незалежних об'єктів
light_bulb = LightBulb.new
fan = Fan.new

light_switch = Switch.new(light_bulb)
fan_switch = Switch.new(fan)

light_switch.turn_on  # Залежність від абстракції
light_switch.turn_off

fan_switch.turn_on
fan_switch.turn_off

В цьому прикладі Switch - це модуль верхнього рівня, який залежить від абстракції SwitchableDevice. Класи LightBulb і Fan реалізують цей модуль, що дозволяє їх використовувати як абстракції, а не конкретні реалізації. Такий підхід полегшує зміну та розширення системи, оскільки можна додавати нові пристрої, не змінюючи клас Switch .