Das Delegator Entwurfsmuster

Das Delegation Entwurfsmuster beschreibt einen Ansatz in der OOP. Demnach übergibt ein Objekt (delegator) eine Aufgabe an ein assoziiertes Hilfsobjekt (delegate). Im Grunde genommen, fordert ein Objekt ein anderes Objekt auf, eine Aufgabe an Stelle zu erledigen; Eine Aufgabe wird delegiert.
Das macht besonders Sinn, wenn Verantwortlichkeiten entkoppelt werden sollen. Außerdem ist es im Zusammenspiel mit Komposition eine mächtige Alternative zur Klassenableitung.
Zur Veranschaulichung stelle man sich Autos vor. Jedes Autos hat einen Motor:

class Engine
  def start
    puts "puff puff"
  end
end

class Car
  def initialize engine
    @engine = engine
  end
end

Bei der Initialisierung des Autos bekommt das Auto den Motor und kann fahren:

engine = Engine.new
car = Car.new engine
car.engine.start # => "puff puff"

Allerdings ist so noch etwas ungünstig.
Wer das Car Objekt nutzen will, muss leider auch die API des Engine Objektes kennen. Analog dazu, interesseiert mich absolut nicht, wie der Motor aufgebaut ist, wenn ich nur Auto fahren will. Ich gehe selbstverständlich davon aus, dass der Motor automatisch startet, wenn ich das Auto anlasse.
Deshalb sollte der Aufruf eher so aussehen:

car.start  # => "puff puff"

Dafür muss das Auto die Aufgabe den Motor zu starten an Engine delegieren. Die Car Klasse muss dafür so aussehen:

class Car
  def initialize engine
    @engine = engine
  end

  def start
    @engine.start
  end
end

Delegieren bedeutet nicht nur das Weiterreichen der Verantwortung für die Implementierung der Business Logik. Es trägt auch zur Entkopplung von Objekten bei, indem die Beziehung zwischen den Objekten nur intern innerhalb eines Objektes behandelt wird und nicht verteilt über die gesamte Anwendung.
Wenn sich die Engine API ändern sollte, verursacht es nun keinen großen Aufwand mehr in der Wartung des Anwendung.
Beim Delegieren der Logik, kann es manchmal Sinn machen, den Namen der message (Methode) zu ändern, damit klar ist, was sie macht:

class Car
  def initialize engine
    @engine = engine
  end

  def move
    @engine.start
  end
end