標籤:
模板模式固然不錯,但其還是有一些缺陷的。比如其實現依賴於繼承並且缺足夠的靈活性。在這時候我們就需要找到一個更加最佳化的解決方案——策略模式。
下面是使用原則模式實現的Report模板
1 # 策略1 2 class HTMLFormatter 3 def output_report title, text 4 puts ‘<html>‘ 5 puts ‘ <head>‘ 6 puts ‘ <title>‘ + title + ‘</title>‘ 7 puts ‘ </head>‘ 8 puts ‘ <body>‘ 9 text.each do |line|10 puts "<p>#{line}</p>"11 end12 puts ‘ </body>‘13 puts ‘</html>‘14 end15 end16 17 # 策略218 class PlainTextFormatter19 def output_report title, text20 puts ‘******** ‘ + title + ‘ ********‘21 text.each do |line|22 puts line23 end24 end25 end26 27 # 環境28 class Reporter29 attr_reader :title, :text30 attr_accessor :formater31 32 def initialize formater33 @title = ‘My Report‘34 @text = [‘This is my report‘, ‘Please see the report‘, ‘It is ok‘]35 @formater = formater36 end37 38 # 可以把指向自己的引用傳入策略中,這樣做雖然簡化了資料流動,但是增加了環境和策略之間的耦合39 def output_report40 @formater.output_report @title, @text41 # @formater.output_report self42 end43 44 end45 46 Reporter.new(HTMLFormatter.new).output_report47 Reporter.new(PlainTextFormatter.new).output_report48 49 # 再來回頭說模板方法模式,50 # 模板方法模式,是尋找共同,然後提取出模板51 # 策略模式,是將不同的方法封裝成一個策略,這些策略不盡相同,難以提取共同部分52 53 # 如果策略足夠簡單,僅有一個方法,那麼可以通過代碼塊傳遞54 class ProcReporter55 attr_reader :title, :text56 attr_accessor :formatter57 58 def initialize &formatter59 @title = ‘My Report‘60 @text = [‘This is my report‘, ‘Please see the report‘, ‘It is ok‘]61 @formatter = formatter62 end63 64 # 可以把指向自己的引用傳入策略中,這樣做雖然簡化了資料流動,但是增加了環境和策略之間的耦合65 def output_report66 @formatter.call self67 end68 69 end70 71 report_html = ProcReporter.new do |context|72 puts ‘<html>‘73 puts ‘ <head>‘74 puts ‘ <title>‘ + context.title + ‘</title>‘75 puts ‘ </head>‘76 puts ‘ <body>‘77 context.text.each do |line|78 puts "<p>#{line}</p>"79 end80 puts ‘ </body>‘81 puts ‘</html>‘82 end83 p report_html.output_report84 85 # 一個簡單的輕量級策略對象的好例子86 a = [‘1‘,‘12‘,‘123‘,‘6234567‘,‘3‘,‘13‘]87 p a.sort88 p a.sort {|a, b| a.length <=> b.length }
ruby中的設計模式--策略模式