Decorator Pattern - Design Pattern in Ruby
あるオブジェクトの機能に追加の機能を付け足したい、
さらにいろいろな組み合わせで追加機能を実装したいという時に使えるパターン。
Interface
元の機能を持ったオブジェクト(ConcreteComponent)と追加機能を実装するオブジェクト(Decorator)という登場人物がいて、同じインターフェース(Component)を持つことで、クライアントからは実際にはどのオブジェクトを扱っているかを気にせずに使用できるようになる。
Traditional implementation
DecoratorオブジェクトにConcreteComponentオブジェクトの参照を渡し、追加機能以外の部分をConcreteComponentに委譲する。
Easing the Delegation
forwardableモジュールをextendすることで、delegateの処理を簡潔に書くことができる。
In Ruby
Wrapping Methods
w = SimpleWriter.new('out') class << w alias old_write_line write_line def write_line(line) old_write_line("#{Time.new}: #{line}") end end
元のメソッドの参照をaliasキーワードで old**に移して、old**をdecorateするメソッドを新たに定義する。
ちょっとした処理を簡単に追加できるが、複数のdecorate処理を買いたい時に、aliasに設定する名前が難しくなってくる。
Decorating with Modules
instance.extend(module) の方法でインタンスにmoduleを設定することで実現する。
簡単なテキストデコレーションを書いてみた。
class TextPrinter def output(str) print str end end module TextEmphasizeDecorator def output(str) print "** " print super(str) print " **" end end module TextBracketsDecorator def output(str) print '(' super str print ')' end end to = TextPrinter.new to.extend(TextEmphasizeDecorator) to.extend(TextBracketsDecorator) to.output('hoge')