ruby中的设计模式--策略模式

模板模式固然不错,但其还是有一些缺陷的。比如其实现依赖于继承并且缺足够的灵活性。在这时候我们就需要找到一个更加优化的解决方案——策略模式。

下面是使用策略模式实现的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     end
12     puts '    </body>'
13     puts '</html>'
14   end
15 end
16 
17 # 策略2
18 class PlainTextFormatter
19   def output_report title, text
20     puts '******** ' + title + ' ********'
21     text.each do |line|
22       puts line
23     end
24   end
25 end
26 
27 # 环境
28 class Reporter
29   attr_reader :title, :text
30   attr_accessor :formater
31 
32   def initialize formater
33     @title = 'My Report'
34     @text = ['This is my report', 'Please see the report', 'It is ok']
35     @formater = formater
36   end
37 
38   # 可以把指向自己的引用传入策略中,这样做虽然简化了数据流动,但是增加了环境和策略之间的耦合
39   def output_report
40     @formater.output_report @title, @text
41     # @formater.output_report self
42   end
43 
44 end
45 
46 Reporter.new(HTMLFormatter.new).output_report
47 Reporter.new(PlainTextFormatter.new).output_report
48 
49 # 再来回头说模板方法模式,
50 # 模板方法模式,是寻找共同,然后提取出模板
51 # 策略模式,是将不同的方法封装成一个策略,这些策略不尽相同,难以提取共同部分
52 
53 # 如果策略足够简单,仅有一个方法,那么可以通过代码块传递
54 class ProcReporter
55   attr_reader :title, :text
56   attr_accessor :formatter
57 
58   def initialize &formatter
59     @title = 'My Report'
60     @text = ['This is my report', 'Please see the report', 'It is ok']
61     @formatter = formatter
62   end
63 
64   # 可以把指向自己的引用传入策略中,这样做虽然简化了数据流动,但是增加了环境和策略之间的耦合
65   def output_report
66     @formatter.call self
67   end
68 
69 end
70 
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   end
80   puts '    </body>'
81   puts '</html>'
82 end
83 p report_html.output_report
84 
85 # 一个简单的轻量级策略对象的好例子
86 a = ['1','12','123','6234567','3','13']
87 p a.sort
88 p a.sort {|a, b| a.length <=> b.length }
原文地址:https://www.cnblogs.com/angelfan/p/4326408.html