Try*_*ard 40 java polymorphism design-patterns strategy-pattern
Strategy模式和PolymorphismJava 之间有什么区别?
我很困惑,通过策略模式实现的任何事情基本上都可以通过多态实现.如果我在这方面错了,请纠正我.
请给我一个根除我的困惑的例子.
rol*_*lan 39
对我来说,CKing帖子和维基百科中的例子的链接已经足够清楚,但我会试着给你一个新的例子.正如他们所说,策略模式主要是一种在运行时更改算法行为的方法.当然,你可以通过许多不同的方式实现这一点(例如持有一个值并使用switch-case,但它不如Strategy Pattern那么好).
假设您正在开发一种基于回合制的战略游戏,其中包括两种单位:步兵和坦克(单位的子类).你的地形可能是平原,铁路或森林.
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;
}
}
Run Code Online (Sandbox Code Playgroud)
任何Unit子类都必须实现fire()方法,因为它们将完全不同(坦克射击重型长距离射击和步兵射击几个短距离射弹).在这个例子中,我们使用普通的多态/继承,因为fire()方法对于任何单位都会有所不同,并且在游戏过程中它不会改变.
class Infantry extends Unit{
public Infantry(){
super(2);
}
void fire(){
//whatever
}
}
class Tank extends Unit{
public Tank(){
super(5);
}
void fire(){
//whatever
}
}
Run Code Online (Sandbox Code Playgroud)
单位也能够移动,并具有一个字段baseMovement,可以保存它可以行走的六边形数量.我们正在开发一个策略游戏,而不是真实世界的模拟,所以我们不关心它们如何移动,我们只想在它们的坐标上添加一个值(在我的例子中,我只使用X坐标以获得更简单的代码).如果所有地形都相同,我们就不需要任何策略对象......但我们需要在运行时更改move()方法的行为!
因此,我们为每种Terrain 实现了一个不同的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);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当任何单位在森林内移动时,我们会打电话
unit.setMovementStrategy(new ForestMovementStrategy());
Run Code Online (Sandbox Code Playgroud)
一旦它进入平原,我们做:
unit.setMovementStrategy(new PlainMovementStrategy());
Run Code Online (Sandbox Code Playgroud)
现在我们可以根据地形改变我们单位移动的距离,我们不需要在任何子类中重写.
我希望这可以帮助您更好地理解差异.
具有核心java示例的多态性与策略模式
多态性是为不同类型的实体提供单一接口.
示例:无论使用何种类型的实际转向机构,方向盘(即接口)都是相同的.也就是说,无论您的汽车是手动转向,动力转向还是齿条齿轮转向,方向盘都能正常工作.因此,一旦您知道如何操作方向盘,您就可以驾驶任何类型的汽车.
在编程中,多态性以两种方式实现:
甲策略模式定义了一组可被可互换地使用的算法.
核心java的示例:java.util.Comparator#compare(),由其他人执行Collections#sort().
运输方式类似于战略设计模式.我们使用汽车,自行车,公共汽车,当地火车等..日常办公的不同策略.
问:策略模式和Java中的多态性有什么区别?
问题肯定令人困惑,因为最初这两个想法之间似乎没有任何关系.
多态性在编程中是一个更广泛的概念,是的,Java中的策略模式使用一种多态性形式编目为包含多态来实现其意图,但这绝不是存在的唯一类型的多态,也不是唯一的方法我将尽快展示战略模式.
多态性也不仅仅存在于Java或面向对象的编程语言中.在所有编程范例中都存在不同形式的多态性,而在所有语言中,您不得不使用多态来实现策略模式(例如,函数式语言).
有关此主题的进一步讨论,请阅读其他答案,我们已经讨论了在没有继承的情况下是否可能存在多态性,并且我为其他类型的多态性提供了有趣的参考和示例,如参数和ad-hoc多态.
理想情况下,这将向您揭示多态性是一个更大的概念,它超越了面向对象编程的界限,甚至超越了继承和子类型.
问:我很困惑,通过策略模式实现的任何事情基本上都可以通过多态实现.如果我在这方面错了,请纠正我.
从我的观点来看,这两个概念之间的关系是:策略模式利用Java等语言中可用的多态性的力量来实现其意图,并且多态性本身可以被视为一种模式.
例如,请考虑GoF书中的这句话:
如果我们假设过程语言,我们可能会包含称为"继承","封装"和"多态"的设计模式.
只是我们很少将多态性视为一种模式,首先是因为它意味着许多事情,并且因为它在不同语言中的实现方式不同,而且因为它通常表现为某种形式的语言特征.
杰森麦克史密斯在他的"元素设计模式"一书中评论了上面的GoF引用:
模式是与语言无关的概念; 当你用一组给定的语言特性和结构在特定的语言中实现它们时,它们采取形式并成为具体的解决方案[...]这意味着谈论"Java设计模式","C++设计模式"有点奇怪","Websphere设计模式"等等,即使我们都这样做.对于我们真正的意思,或者应该意味着:设计模式是用Java,C++,WebSphere等实现的,无论语言或API如何,它都是一种温和的懒惰形式.
因此,正如您所看到的,您正在从Java实现的角度思考策略模式,但在其他语言范例中,这种模式可能已经以不同的方式实现,可能根本不使用继承,例如,在纯函数中编程语言这肯定是使用高阶函数和函数组合实现的.
因此,这将是一种策略模式实现,而根本不依赖于包含多态性.在函数组合策略中,我们可能仍在使用其他形式的多态(例如参数),但这不是策略模式的要求
问:请给我一个根除我的困惑的例子.
如上所述,在Java中,我们可能被迫使用包含多态来实现策略模式,但如上所述,模式不属于特定语言,因此如果我们将策略模式视为概念生活在任何语言边界之外,您将很容易看到其他语言以不同的方式实现这一点.
在一些假设的函数式语言中,我可能有一个函数从文件中读取一些数据,也许文件是加密的,你需要提供一个解密策略:
function readFile(path: String, decrypt: string -> string) {
return decrypt(loadFromDisk(path));
}
Run Code Online (Sandbox Code Playgroud)
并且该decrypt参数是一个服务于策略模式目的的函数,它封装了一个可互换的算法.
现在你可以做到
readFile("customers.txt", aes)
readFile("finance.txt", blowfish)
Run Code Online (Sandbox Code Playgroud)
在哪里aes和blowfish在解密功能的策略.
有许多语言可以像这样工作,SML,Haskell,JavaScript等.
如果您要建立一个类比,其中:
那么差异就是耦合程度,在第一种情况下非常强,而在第二种情况下,任何外国代码都可以通过贡献其战略实施来参与你的阶级逻辑.
| 归档时间: |
|
| 查看次数: |
8944 次 |
| 最近记录: |