jlaky 发表于 2013-2-7 18:55:12

Design Patterns in Ruby [Digest 3] Strategy

The Template method is build around inheritance, the inheritance has the nature born relationship.
So the Strategy give a delegate solution.
 
So we use the strategy implementation:
 
 
class Formatterdef output_report( title, text )raise 'Abstract method called'endendclass HTMLFormatter < Formatterdef output_report( title, text )puts('<html>')puts(' <head>')puts(" <title>#{title}</title>")puts(' </head>')puts(' <body>')text.each do |line|puts(" <p>#{line}</p>" )endputs(' </body>')puts('</html>')endendclass PlainTextFormatter < Formatterdef output_report(title, text)puts("***** #{title} *****")text.each do |line|puts(line)endendend 
So the Report is much simpler:
 
 
class Reportattr_reader :title, :textattr_accessor :formatterdef initialize(formatter)@title = 'Monthly Report'@text = [ 'Things are going', 'really, really well.' ]@formatter = formatterenddef output_report@formatter.output_report( @title, @text )endend 
Usage is as below:
 
report = Report.new(HTMLFormatter.new)report.output_report 
The key idea of Strategy is to define a family of strategy objects those are used by the context class,
its use composition and delegation rather than inheritance, it is easy to switch strategies at runtime
 
 
there is a problem about sharing data between context and strategies,
the writer gives a example as below:
 
class Reportattr_reader :title, :textattr_accessor :formatterdef initialize(formatter)@title = 'Monthly Report'@text = ['Things are going', 'really, really well.']@formatter = formatterenddef output_report@formatter.output_report(self)endendclass Formatterdef output_report(context)raise 'Abstract method called'endendclass HTMLFormatter < Formatterdef output_report(context)puts('<html>')puts(' <head>')puts(" <title>#{context.title}</title>")puts(' </head>')puts(' <body>')context.text.each do |line|puts(" <p>#{line}</p>")endputs(' </body>')puts('</html>')endend 
This technique simplifies the data flow but increases the coupling.
 
 
Then Ruby Duck Typing philosophy shows that we don't need the Formatter class any more. 
页: [1]
查看完整版本: Design Patterns in Ruby [Digest 3] Strategy