多态性与策略模式
模式和Java有什么区别?Strategy
Polymorphism
我感到困惑的是,通过策略模式实现的任何东西基本上都可以通过多态性来实现。如果我在这方面错了,请纠正我。
请也为我提供例子,以消除我的困惑。
模式和Java有什么区别?Strategy
Polymorphism
我感到困惑的是,通过策略模式实现的任何东西基本上都可以通过多态性来实现。如果我在这方面错了,请纠正我。
请也为我提供例子,以消除我的困惑。
对我来说,来自CKing帖子的链接和维基百科中的示例已经足够清楚了,但我会尝试给你一个新的示例。正如他们所说,策略模式主要是一种在运行时改变算法行为的方法。当然,您可以通过许多不同的方式实现这一目标(例如持有值和使用开关案例,但它不会像策略模式那样好)。
假设您正在开发一款回合制战略游戏,其中包含两种单位:步兵和坦克(单位的子类)。您的地形可以是平原,铁路或森林。
class Unit{
MovementStrategy ms;
final int baseMovement;
int x,y;
public Unit(int baseMovement){
this.baseMovement = baseMovement;
}
abstract void fire();
void moveForward(){
x = x + ms.getHexagonsToMove(baseMovement);
}
void setMovementStrategy(MovementStrategy ms){
this.ms = ms;
}
}
任何单位子类都必须实现fire()方法,因为它对他们来说是完全不同的(坦克射击重型长距离子弹和步兵射击几发短距离轻型子弹)。在这个例子中,我们使用正常的多态性/继承,因为fire()方法对于任何单位来说都是不同的,并且在游戏过程中不会改变。
class Infantry extends Unit{
public Infantry(){
super(2);
}
void fire(){
//whatever
}
}
class Tank extends Unit{
public Tank(){
super(5);
}
void fire(){
//whatever
}
}
单位也能够移动,并具有一个字段基础移动,该移动保存它可以行走的六边形的数量。我们正在开发一个策略游戏,而不是现实世界的模拟,所以我们不在乎它们如何移动,我们只想为它们的坐标添加一个值(在我的示例中,我只使用X坐标来获得更简单的代码)。如果所有的地形都是一样的,我们就不需要任何策略对象了......但是我们需要在运行时改变 move() 方法的行为!
因此,我们为每种地形实现不同的 MovementStrategy 类,并对游戏进行编程,以触发在每个六边形上移动的任何单位的 setMovementStrategy()。而且我们甚至不需要在 Unit 子类中编写任何其他内容。
interface MovementStrategy{
public int getHexagonsToMove(int base);
}
class PlainMovementStrategy implements MovementStrategy{
public int getHexagonsToMove(int base){
return base;
}
}
class RailroadMovementStrategy implements MovementStrategy{
public int getHexagonsToMove(int base){
return base*3;
}
}
class ForestMovementStrategy implements MovementStrategy{
public int getHexagonsToMove(int base){
return (int)(base/2);
}
}
现在,当任何单位在森林内移动时,我们调用
unit.setMovementStrategy(new ForestMovementStrategy());
一旦它到达平原,我们就会这样做:
unit.setMovementStrategy(new PlainMovementStrategy());
现在,我们能够根据地形更改单位的移动距离,并且不需要在任何子类中重写。
我希望这有助于您更好地了解差异。
我感到困惑的是,通过策略模式实现的任何东西基本上都可以通过多态性来实现。
没有方向盘就不能开车。这并不意味着方向盘就是一辆汽车。同样,策略模式依赖于多态性,但这并不意味着它们是一回事。
策略模式的目的是促进组合 (has-a) 而不是继承 (is-a) 的使用。不是您的类从超类继承行为,而是在单独的类中定义行为,并且您的类具有对它的引用。
就示例而言,请看一下这个做得很好的答案。