2012-10-27 7 views
28

Wahrscheinlich fehlt mir etwas einfaches, aber ich verstehe nicht, wie Rubys DelegateClass Methode zu verwenden, ich meine, wenn es statt SimpleDelegator Klasse zu verwenden. Zum Beispiel alle folgenden scheinen meist identisch zu arbeiten:Wann Ruby DelegateClass anstelle von SimpleDelegator verwenden? (DelegateClass-Methode vs. SimpleDelegator-Klasse)

require 'delegate' 

a = SimpleDelegator.new([0]) 
b = DelegateClass(Array).new([0]) 
c = DelegateClass(String).new([0]) 
a << 1 
b << 2 
c << 3 
p a # => [0, 1] 
p b # => [0, 2] 
p C# => [0, 3] 

Beachten Sie, dass es keine Rolle scheint die Klasse zu DelegateClass geben wird.

+0

Nach einiger Zeit darüber nachzudenken, das ganze Delegator Pattern mir sieht aus wie ein schnell schmutzig Hack :). Sie senden eine Nachricht, und Sie wissen nicht, welche Klasse für die Beantwortung zuständig ist. Der Delegator durchläuft alle Nachrichten, die er nicht erkennt, ohne zu wissen, ob und wie er beantwortet wird (andernfalls könnte er als Unterklasse realisiert werden, oder die Komposition verwenden, nicht wahr?). Die ursprüngliche Klasse kontrolliert wirklich nichts mehr und weiß nicht einmal, dass es einen Delegierer zwischen ihr und dem Rest der Welt gibt. – Alexey

Antwort

21

Verwenden Sie die Unterklasse SimpleDelegator, wenn Sie ein Objekt wünschen, das während seiner Lebensdauer über ein eigenes Verhalten verfügt und an verschiedene Objekte delegiert.

Im Wesentlichen sagen Sie DelegateClass, wenn die Klasse, die Sie erstellen, kein anderes Objekt erhalten wird. TempFile in Ruby wird nur ein Dateiobjekt verzieren SimpleDelegator kann auf verschiedene Objekte wiederverwendet werden.

Example:

require 'delegate' 


class TicketSeller 
    def sellTicket() 
    'Here is a ticket' 
    end 
end 


class NoTicketSeller 
    def sellTicket() 
    'Sorry-come back tomorrow' 
    end 
end 


class TicketOffice < SimpleDelegator 
    def initialize 
    @seller = TicketSeller.new 
    @noseller = NoTicketSeller.new 
    super(@seller) 
    end 
    def allowSales(allow = true) 
    __setobj__(allow ? @seller : @noseller) 
    allow 
    end 
end 

to = TicketOffice.new 
to.sellTicket » "Here is a ticket" 
to.allowSales(false) » false 
to.sellTicket » "Sorry-come back tomorrow" 
to.allowSales(true)  » true 
to.sellTicket » "Here is a ticket" 

Hier ist eine weitere gute Erklärung a-delegate-matter

+3

Sie sollten einen 'SimpleDelegator' nicht für verschiedene * Typen * von Objekten verwenden, obwohl es für andere * Instanzen * sinnvoll ist, sie wiederzuverwenden; [die Dokumente] (http://ruby-doc.org/stdlib-2.1.0/libdoc/delegate/rdoc/SimpleDelegator.html#__setobj__-method) sagen explizit über '#__ setobj__':" Es ist wichtig, dies zu beachten SimpleDelegator-Methoden werden nicht geändert. ... wahrscheinlich möchten Sie nur die Delegierung auf Objekte desselben Typs wie den ursprünglichen Delegaten ändern. " – nickgrim