策略设计模式及其Java实现

策略设计模式思想

基本思想

  和大多数设计模式一样,策略设计模式是为了在软件系统中满足某项功能的开闭原则。对于某一个特定的功能Functionality F, 如果在未来很可能有多种不同的方式实现,并且无法在目前的开发阶段预测该功能的实现方式的种类,这时候就可以使用策略模式。
  在开发中经常会遇到的问题是,功能F有多种可能的实现方式,并且不应该,也没有办法在开发的时候就确定所有的实现方式。也就是说必须要把该F的多样化的实现方式暴露为可扩展的。这种情况在游戏开发中尤其常见,举一个简单的例子,游戏中不同难度的AI根据不同的策略对玩家的操作做出反应,简单的AI总是直直地向玩家所在的地方释放技能,而更高难度的AI却可以从玩家的运动信息中预判玩家的走位而提前释放技能。
  再举一个例子,决战平安京中,经济信息中的排序是按照玩家现有的经济总量进行排序的,但是最后结算的时候却需要综合各种因素从玩家中选出得分最高的人成为MVP,这就是对玩家进行排序的不同策略,而比较排序的顺序完全依赖于比较的策略
  最后一个例子,火属性的玩家在火属性高的场地有更高的伤害,但是冰属性的玩家在火属性高的场地伤害却会变低,这也是计算伤害的不同策略
  以上几种情况相同的地方在于,难以或者根本就无法在开发的时候决定目前到底有多少种情况。要在设计游戏之处就确定好每个难度的AI释放技能的细节是非常困难的;在游戏设计之初就设计好每个属性的玩家在计算伤害的时候的各种情况仍然是非常困难的。但是借助策略设计模式,我们就可以将这些细节留到后面,用扩展的方式来慢慢实现他们。

实现思想

  每当AI要确定释放技能的方向时,就调用determinDirection(SeceneInfo info, Strategy strategy) 方法来确定施法方向,其中info是确定施法方向需要的信息,strategy是确定施法方向所需要的策略。 同理,每当需要判断不同属性的玩家的伤害的时候,就调用judgeDPS(SeceneInfo info, JudgeDPSStrategy strategy) 方法来判断玩家的伤害。
  这样一来,在开发的过程中,就不必要对这些实现上的细枝末节反复推敲,可以快速搭建出可扩展的框架。

Java实现

将strategy抽象为一个接口

  其实上面已经给出了基本的雏形。这里的关键是如何利用java的类型和运行时系统使写出的策略模式代码优雅简洁。因为策略模式很少会涉及到并发执行多种策略模式的情况,所以基本上不会跟运行时扯上什么关系,所以Java中实现策略模式基本上都是在静态类型系统中完成的。
  从上面的代码可以看出来,在Java中,Strategy 很显然应当被实现为一个接口。该接口有一系列的获取/修改Info的方法,(其实也可以让它修改非info的某个对象的某个字段,只要耦合性不会高到难以维护代码就行)。 从抽象的角度来讲,Strategy 接口也许应该总是有一个execute 方法,但总的来说不是必要的,要怎样使用这个策略是策略的调用函数应该决定的,我们不应该对怎样使用策略做出假设,而应该把策略接口的设计交给使用它的人来完成。

利用静态类型(包括泛型)

  在Java中,一个抽象的功能F在绝大多数情况下是使用一个方法来表示的(实际上我觉得应该只有这个表示方法)。一个方法有输入、输出和副作用。这里为了方便讨论,把副作用看作输出的一种。 一类策略的输入和输出应该是类似的,他们应该至少能通过某种类型系统约束起来(如前所述,绝大多数情况下应该约束到静态类型),以至于策略使用者可以以一种的统一的方式使用策略的输出。
  简单情况下,策略的输入输出最好是固定类型。即从固定类型的对象中以不同的方式获取信息,然后返回固定类型的不同结果。比如AI施法策略中,策略需要场景信息SeceneInfo 作为输入,返回Vector3类型对象表示施法方向。
 但是这样的设计总体缺乏扩展性,我们可能需要对不同类型的对象执行类似的策略,尤其是输出为副作用的策略,需要对不同的输入类型进行不同的操作。这时候,在Java语言中表达参数满足某种类型,只需要加上泛型就可以实现了。

// 一个例子:游戏中有的角色需要根据场地的崎岖程度调整步行速度,有的角色则不需要。
interface WalkingStrategy<W extends Walkable, I extends Info> {
	double walking(I info, W walker);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值