我试图真正理解如何用OOP术语思考,所以我脑海中有一个半假设的场景,我正在寻找一些想法。
如果我想为不同类型的人互动设计模拟,每个人都可以获得不同“技能”的不同熟练程度,那么最佳方法是什么?
这真的是“技能”的事情,我有点陷入其中。我的要求如下:
- 每个人要么“有”技能要么没有
- 如果人们有技能,他们也具有与技能相关的“熟练程度”
- 我需要一种方法来找到和挑选每个具有某种技能的人,或者某种程度上
- 设计需要是可扩展的(即,我需要能够在以后添加更多“技能”)
我考虑了以下选项:
对于我包含的每一项技能都有一个巨大的枚举,并且人类包含一个 “int Skills [TOTAL_NUM_SKILLS]”成员。该阵列的“未获得”技能为零,而“获得技能”的熟练程度为1到(最大)。
具有相同的巨型枚举,并且人员类包含技能地图(来自枚举)和与技能相关联的数字,以便您只能将获得的技能添加到地图并关联数字这样。
为每一项技能创建一个具体的类,并且每个技能都从一个抽象基类继承(比如ISkill),并让person类有一个ISkill的地图
实际上,选项1似乎是一种直截了当的严肃方式。请批评;有什么理由不接受这个吗?是否有更面向对象的方式来做到这一点?
我知道选项3现在没有多大意义,但是如果我决定稍后扩展它以使技能不仅仅是与他们相关的熟练程度(即实际上将新行动与技能相关联)(ISkill :: DoAction等),这是否有意义?
对于这个广泛的问题,我很抱歉,我只想看看这条思路是否有意义,或者我是否完全咆哮错误的树。
答案 0 :(得分:1)
选项1的问题是未来的兼容性。假设您将此框架发送给客户。现在,客户已为每个人构建了Skill
值的数组,其长度为TOTAL_NUM_SKILLS
。但是,只要您尝试添加其他技能,尤其是当您尝试重新排序技能时,此操作就会失败。
如果客户使用RPC框架,客户端和服务器通过网络传递Person
个对象,该怎么办?现在,除非客户在同一时间升级客户端和服务器,否则RPC调用会中断,因为现在客户端和服务器需要不同长度的数组。这可能特别棘手,因为客户可能只拥有客户端,或者只拥有服务器,并且无法同时升级这两者。
但它变得更糟。假设客户端已在某个文件中向磁盘写出Person
对象。如果他们决定将某个人序列化为一个简单的数字列表,那么新技能将导致反序列化代码失败。更糟糕的是,如果你对枚举中的技能进行重新排序,反序列化代码可能会正常工作,但会给出错误的答案。
我完全按照你命名的原因选择选项3:稍后你可以添加更多功能,并安全地这样做(好吧,除非every public change is a breaking change如果你的客户在语言中运用某些边缘情况,这个事实除外。
答案 1 :(得分:0)
如果您想在不改变整体程序结构的情况下经常添加技能,我会考虑某种外部数据文件,您可以在不重新编译代码的情况下进行更改。想想你如何在一个非常大的项目中做到这一点。选择技能的人可能是没有编程能力的设计师。他可以在XML文件中编辑技能,但不能在C ++代码中编辑。
如果您使用XML定义了技能,那么它自然会扩展为使用每种技能存储更多数据。您的播放器也可以序列化为XML文件。
当您在运行时设置玩家的技能时,您可以从XML文件构建一个键入技能名称的哈希表。如果枚举玩家的技能比查询玩家是否具有某种技能更常见,那么你可以使用一个字符串向量。
当然,此解决方案将使用更多内存并且运行速度比枚举解决方案慢。但除非你在你的计划中与数百万玩家打交道,否则它可能会足够好。