设计模式与动态语言 之 策略模式(strategy)

策略模式还有个别名叫政策模式(Policy),属对象行为型模式。


意图:[b]定义一系列算法,把它们一个个封闭起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化[/b]

动机:把算法硬编写在使用他们的类中是不合适的。

不合适的地方有:
[list]
[*]代码乱
[*]多余的引用
[*]修改困难
[*]不好测试
[/list]


适用性:
[list]
[*]许多相关的类仅仅是行为不同
[*]需要使用一个算法的不同变体
[*]一个类定义了多种行为,并且这些行为在操作用以多个条件语句的形式出现。
[/list]

结构:

[img]http://dl.iteye.com/upload/attachment/166526/0e1da56d-1953-32c6-a2e7-0df728287ded.png[/img]

在动态语言里边(如Ruby),可以没有父类,用Proc和代码块可以简单实现策略模式

如:
hello = lambda {
puts "I am a proc"
}

hello.call


def run_it
puts "before"
yield
puts "after"
end

run_it do
puts "I am a yield"
end


在Ruby中还有很多轻量级策略对象,像 sort map select each 等。

效果:
[list]
[*]使算法或行为可重用
[*]继承有助于取出这些算法的公共功能
[*]算法实现与Context分离,易切换,理解,扩展
[*]算法委托给父类,省去部分Case
[*]方便单元测试
[/list]

用该模式应注意:
[list]
[*]环境对象和策略对象的接口弄错。将完整一致的,可独立的工作移出环境对象, 然后用策略对象来代理它。
[*]注意,如果你将你的环境对象和某一个策略对象过紧耦合,而无法设计中推出第二个和第三个策略对象, 那就是误用
[*]切换时必须了解不同的Strategy
[/list]

看了上面的介绍大家可能会觉得策略模式跟前面讲到的[url=http://jim-jin.iteye.com/blog/508295]模板方法[/url]没什么区别,不就都是将算法封装吗?下面讲下他们的区别:

[list]
[*]策略模式用组合,模版模式用继承,说白了就是一个封装一组算法(多算法),一个封装一个算法(单算法)。
[*]模版模式就是算法在父类中,子类不会完全改写算法,可以改写部分,或称关键部分,但整体的算法不变,可以节省大量代码
[*]策略侧重不同的行为的改变在统一的接口下,强调多态下面行为的执行过程,处理过程,可以从用户那里接受参数,只要用户提供的策略符合接口
[*]策略模式所有的算法均在子类中完成,强调行为即算法的不同,可以使程序更灵活,而模版模式中子类不能改变父类算法结构.
[/list]

下面是一个例子:


class Hero
def kill(bug, skill)
skill.do(bug)
end
end

# 技能
class Skill
def do(bug="bug")
raise "This is abstract method"
end
end

# 雷电
class Thunder < Skill
def do(bug="bug")
puts '延迟3秒'
puts '闪电2下'
puts '连续的打雷'
puts "#{bug} 减血1000"
end
end

# 地震
class Earthquake < Skill
def do(bug)
puts "#{bug} 减血500"
puts '连续的地震波2秒'
puts "#{bug} 眩晕5秒"
end
end

# 旋风
class Whirlwind < Skill
def do(bug)
puts '范围100 旋风5秒并移动'
puts "#{bug} 连续减血150/每秒 "
end
end

puts "\r\n"
puts '打猪'
puts "------------"
Hero.new.kill('小猪', Thunder.new)

puts "\r\n"
puts '打小白'
puts "------------"
Hero.new.kill('小白', Earthquake.new)

puts "\r\n"
puts '打牛'
puts "------------"
Hero.new.kill('大牛', Whirlwind.new)


[url=http://dl.iteye.com/topics/download/c9d59dc3-0123-35ef-8992-85012739607a]源码文件点击下载[/url]

类图:

[img]http://dl.iteye.com/upload/attachment/166619/5be08893-aeb6-37a1-aaef-c4ddbc3e2f84.jpg[/img]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值