R ” PAT T E R N S adapter chain of responsibility visitor mediator proxy flyweight command singleton builder bridge abstract factory factory method template method prototype observer composite strategy decorator facade iterator memento interpreter state
D E class Button def initialize(command); @command = command; end def on_click; @command.call; end end class Copy def call; clipboard.text = @page.marked_text; end end class Paste def call @page.text[@cursor.position] += @clipboard.text end end copy_button = Button.new(Copy.new) paste_button = Button.new(Paste.new)
D E class Button def initialize(&blk); @command = blk; end def on_click; @command.call; end end copy_button = Button.new do clipboard.text = @page.marked_text end paste_button = Button.new do page.text[cursor.position] += clipboard.text end
I A N T S class Paste def call @start_position = cursor.position @text = clipboard page.text[@start_position] += @text end def undo text.slice!(@start_position, @text.length) end end
initialize(text); @text = text; end def render; @text.render; end end class ItalicTextDecorator < TextDecorator def render; "<i>#{super}</i>"; end end D E C O R AT O R - C O D E
LT E R N AT I V E module ItalicTextDecorator def render; "<i>#{super}</i>"; end end module BoldTextDecorator def render; "<b>#{super}</b>"; end end text = Text.new("this is text") text.extend(ItalicTextDecorator) text.extend(BoldTextDecorator) text.render # => <b><i>this is text</i></b>
E C A S E • I’m writing a text editor • I want to implement opening multiple files • for each file a new window should open that will print text on the screen
raises an error Settings.instance # <Settings:0x007fcea4142bf0> Settings.instance # <Settings:0x007fcea4142bf0> Settings.instance # <Settings:0x007fcea4142bf0> S I N G L E T O N - C O D E
notify_observers end def notify_observers @observers.each { |o| o.notify(self) } end def add_observer(observer) @observers << observer end end O B S E R V E R - C O D E
H O D Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
N S 2 0 Y E A R S L AT E R • considered harmful (Singleton, Observer) • useless in languages with certain features (Abstract Factory) • deprecated (Observer) • useful in rare cases (Command, Builder)
N S 2 0 Y E A R S L AT E R • core features (Iterator) • standard library (Observer, Singleton) • commonly used (Adaptor, Decorator) • used for communication purpose (Iterator, Decorator, Observer)
R. Olsen “Design Patterns in Ruby” • E. Gamma et al. “Design Patterns: Elements of Reusable Object-Oriented Software” • C. Haynes “Design Patterns and the Proper Cultivation Thereof” (talk) • http://c2.com/cgi/wiki