2012-10-27 5 views
28

おそらく私は単純なものがありませんが、RubyのDelegateClassメソッドを使用する方法が分かりません。SimpleDelegatorクラスの代わりに使用することを意味します。たとえば、次のすべては、ほとんど同じように動作するように見える:DelegateClassに渡されたクラスは関係していないようだということSimpleDelegatorの代わりにRuby DelegateClassを使用するのはいつですか? (DelegateClassメソッドとSimpleDelegatorクラス)

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] 

注意を。

+0

は、いくつかの時間のためにそれについて考えた後で、全体の委任者のパターンは、迅速な汚いハック:)のように私には見えます。あなたはメッセージを送信し、あなたはどのクラスが応答するのかを知らない。委譲者は、認識できないすべてのメッセージを、それらが応答するかどうか、またどのように応答するかを知らなくても通過させます(そうでなければ、サブクラスとして実現できますか?元のクラスは実際にはもう何も制御しませんし、それと他の世界との間に委任者があることさえ知りません。 – Alexey

答えて

21

独自の動作を持ち、寿命の間に異なるオブジェクトに委譲するオブジェクトが必要な場合は、サブクラスSimpleDelegatorを使用します。

作成しているクラスが別のオブジェクトを取得しない場合は、基本的にはDelegateClassを使用してください。 RubyのTempFileはFileオブジェクトのみを装飾します SimpleDelegatorは別のオブジェクトで再利用できます。ここで

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" 

別の良い説明a-delegate-matter

+3

異なる*タイプ*のオブジェクトに対して 'SimpleDelegator'を再利用するべきではありませんが、異なる*インスタンスに対して再利用することはOKです。 [docs](http://ruby-doc.org/stdlib-2.1.0/libdoc/delegate/rdoc/SimpleDelegator.html#__setobj__-method)は '#__ setobj__'について明示的に言っています:"これは重要ですSimpleDelegatorのメソッドが変更されることはありません。おそらく元のデリゲートと同じタイプのオブジェクトに代理を変更したいだけです。 – nickgrim

関連する問題