定义:把算法独立出来放在一个独立的对象中
通用定义:策略对象被看做是一群包裹在对象中并知道自己要干什么的可执行代码
应用:其实是对template method中继承的缺点进行改进。
特点:将算法的使用和算法的实现放在不同的类中,实现了数据的分离。算法的使用类叫做context类, 算法的实现类是strategy类
代码实现:在context类的初始化方法中设定strategy类的对象变量,通过context的实例化对象来调用实例方法来实现strategy类实例化对象的实例方法。
代码的的直观实现1:通过参数的形式来传递context类和strategy类之间的数据
class Report
attr_reader :name
def initialize(format)
@format = format
@name = "jayzen"
end
def out_report
@format.report(@name)
end
end
class TextFormat
def report(name)
puts "text name: #{name}"
end
end
report = Report.new(TextFormat.new)
report.out_report
上述代码的问题是传递的参数如果太多,有些参数根本用不到,所以进行了下面的简化操作。
代码的的直观实现2:让环境对象把一个指向自己的引用作为参数传入策略中
#针对上面的代码实现
class Report
attr_reader :name
def initialize(format)
@format = format
@name = "jayzen"
end
def out_report
@format.report(self)
end
end
class TextFormat
def report(context)
puts "text name: #{context.name}"
end
end
report = Report.new(TextFormat.new)
report.out_report
上面的代码问题需要新建一个strategy类,关于策略模式的定义是把算法独立出来放在一个独立的对象中,这里可以算法的实现包装到一个代码块中。
策略算法的更通用定义:策略对象被看做是一群包裹在对象中并知道自己要干什么的可执行代码
class Report
attr_reader :name
def initialize(&format)
@format = format
@name = "jayzen"
end
def out_report
@format.call(self)
end
end
format = lambda do |context|
puts "format name #{context.name}"
end
report = Report.new(&format)
report.out_report
数据传递:上面的三个代码实例都出现了数据传递,数据来源地是Content类,数据的流向方向Strategy类,所以在一定程度上存在两个类之间耦合。在Content类中接口实现的具体方式是通过Strategy的方法来进行具体实现的。
实现案例:array的sort的用法
#arr = ["abc", "ok"]
arr.sort #进行排序,会根据数组中对象的自然次序进行排序
#如果要根据数组的长度进行排序,这就是一个策略模式的例子
arr.sort{|a, b| a.length <=> b.length }
https://medium.com/@joshsaintjacque/ruby-the-strategy-pattern-16c98b99b373
http://blog.51cto.com/blackanger/90916
http://www.cnblogs.com/nbkhic/archive/2011/07/23/2114794.html