我正在用Java制作一个非常简单的2D RPG。我的目标是尽可能简单地执行此操作。根据基础知识,我的班级结构目前是这样的:
到目前为止,我已经给了Player类一个NPC Humanoids的“派对”ArrayList,而NPC Humanoids类是一个“雇佣”的布尔值。
然而,我的战斗方法很笨拙,在实施战斗之前使用if来检查战队规模,例如
public class Player extends Humanoids {
private ArrayList<Humanoids> party;
// GETTERS AND SETTERS for party here
//...
public void fightEnemy(Enemy eneObj) {
if (this.getParty().size() == 0)
// Do combat without party issues
else if (this.getParty().size() == 1)
// Do combat with party of 1
else if (this.getParty().size() == 2)
// Do combat with party of 2
// etc.
我的问题是,在面向对象设计中思考,我是否能够以尽可能简单的代码完成这项工作?还有更好的方法吗?
答案 0 :(得分:7)
“我的问题是,在面向对象设计中思考,我是否能够以尽可能简单的代码完成这项工作?”
不,您的描述使用的基本动词描述了您的设计是如何构建在过多的继承上的。
物理对象具有 x和y维度(位置)
[漫游对象是具有可变位置的物理对象]
人形对象是具有库存的漫游对象
玩家是一个单身人形对象,可以拥有一方
[派对有一个玩家,而 最多 4 NPC Humanoids
组合虽然在面向对象设计中很少强调,但在代码中起着重要作用。这就是具有 / is-a 区别经常用于分析的原因。
通过将玩家声明为单身人士,您增加了类型复杂性并可能限制您的设计。如果你想在未来的某个时间点拥有两名球员怎么办?怎么样?这不是一个不合理的扩展,但需要你打破使用的单一反模式。如果你只想要一个玩家,只需要实例化一个;将单一性假设编码到类中是不必要的限制。请记住,编码员必须肯定地称呼构造函数,不必担心玩家会自发出现。
一个物体有一个位置,很棒:通过构图给它一个。可以更改位置,因此定义position :: move()。玩家可能有一个人类控制器,可以将其与NPC区分开来,但是 - 根据定义 - 非玩家角色确实是角色,具有控制权的角色来自玩家。你想给NPC玩家控制吗?很多游戏都有,但如果你已经在一个类中编写了玩家角色依赖,那么NPC将永远是一个NPC。
另外,你有多确定4(或5)对于派对来说是个好人数? Zero, One, Infinity原则说如果你允许多个,允许任意数字。如果您没有在设计中硬编码“五个”,则会限制灵活性。
我通常建议设计师认为继承是一种最后的方法,因为有过度使用的历史。设计可以是OOP而根本没有继承。多态性很酷,但封装和抽象也是如此,或许更是如此。
答案 1 :(得分:2)
那么,从基本的编程角度来看,忘记整体设计,而不是拥有if
结构,你应该有一个方法,将派对大小作为参数。这样,您就可以传递this.getParty().size()
并删除if
s。
即
combatManager.fight(this.getParty().size(), eneObj);
combatManager
是一个对象(或类,如果你想要一个静态版本),知道如何制作fight
。
正如我所说,这不是您的设计的解决方案,只是避免if
s的更好方法。
Player
课程不应该让事情发生争执,所以也许你可以将你的fightEnemy
方法更改为engageEnemy
或其他东西,然后让它转到使用了正确的参数。
答案 2 :(得分:0)
也许这是使用Strategy Design Pattern的好机会。通过这种方式,您可以更改在添加或删除党员时使用的战斗策略,而不是每次战斗。
答案 3 :(得分:0)
该玩家是该党的一部分。 NPC也是党的一部分。为什么玩家会处理NPC战斗?我认为你应该将这个逻辑添加到NPC类中(扩展Humanoid)并添加一些AI,以便NPC在它们组合在一起时将与播放器和其他NPC一起动作。