Oop 模拟与其他对象关联的大量对象(“有一个”)

Oop 模拟与其他对象关联的大量对象(“有一个”),oop,composition,Oop,Composition,我试图真正了解如何用面向对象的术语进行思考,所以我脑海中有一个半假设的场景,我在寻找一些想法 如果我想为不同类型的人设计一个相互交流的模拟,每个人都可以在不同的“技能”中获得不同的熟练程度,那么什么是实现这一点的最佳方法 这真的是我有点迷恋的“技能”的东西。我的要求如下: -每个人要么“有”一项技能,要么没有 -如果人们有技能,他们也有与技能相关的“熟练程度” -我需要一种方法来找到并挑选出每一个有一定技能或水平的人 -设计需要可扩展(即,我以后需要能够添加更多的“技能”) 我考虑了以下选择:

我试图真正了解如何用面向对象的术语进行思考,所以我脑海中有一个半假设的场景,我在寻找一些想法

如果我想为不同类型的人设计一个相互交流的模拟,每个人都可以在不同的“技能”中获得不同的熟练程度,那么什么是实现这一点的最佳方法

这真的是我有点迷恋的“技能”的东西。我的要求如下:
-每个人要么“有”一项技能,要么没有
-如果人们有技能,他们也有与技能相关的“熟练程度”
-我需要一种方法来找到并挑选出每一个有一定技能或水平的人 -设计需要可扩展(即,我以后需要能够添加更多的“技能”)

我考虑了以下选择:

  • 对于我包含的每一项技能都有一个巨大的枚举,并让person类包含一个 “智力技能[总技能]”成员。数组中的“未习得”技能为0,而“习得技能”的熟练程度为1到(最大值)

  • 使用相同的巨型枚举,并让person类包含技能地图(来自枚举)和与技能相关联的数字,以便您只需将获得的技能添加到地图中,并以这种方式关联一个数字

  • 为每项技能创建一个具体的类,并让每个类从抽象基类(比如说ISkill)继承,让person类拥有ISkill的映射

  • 事实上,选项1似乎是一种直截了当的方式。请批评;这是不可接受的原因吗?有没有更面向对象的方法来实现这一点

    我知道选项3现在没有多大意义,但如果我决定以后扩展它,让技能不仅仅是与熟练程度相关的东西(即,实际上将新动作与技能相关联(ISkill::DoAction,等等),这作为选项有意义吗


    对不起,这个问题太大了,我只是想看看这条思路是否有意义,或者我是不是找错了方向。

    选项1的问题是未来的兼容性。假设您将此框架发送给客户。现在,客户已经构建了此
    技能
    值数组,即长度
    总数为每个人杀死
    。但一旦你尝试添加另一项技能,尤其是当你尝试重新排列技能时,此操作就会失败

    如果客户使用的RPC框架中,客户机和服务器通过线路传递
    Person
    对象,该怎么办?现在,除非客户同时升级客户机和服务器,否则RPC调用会中断,因为现在客户机和服务器需要不同长度的数组。这可能特别棘手,因为客户r可能只拥有客户端或服务器,并且无法同时升级两者

    但情况会变得更糟。假设客户端在某个文件中将
    Person
    对象写入磁盘。如果他们决定将Person序列化为简单的数字列表,则新技能将导致反序列化代码失败。更糟的是,如果您在枚举中重新排序技能,反序列化代码可能工作正常,但给出了错误的答案


    我喜欢选项3的原因正是因为您命名的原因:以后您可以添加更多功能,并且可以安全地这样做(好吧,除非您的客户使用该语言执行某些边缘案例).

    选项1的问题是未来的兼容性。假设您将此框架发送给客户。现在,客户已经为每个人构建了
    技能
    值数组,即长度
    总技能数
    。但一旦您尝试添加其他技能,尤其是尝试重新排序技能时,此操作就会失败。

    如果客户使用的RPC框架中,客户机和服务器通过线路传递
    Person
    对象,该怎么办?现在,除非客户同时升级客户机和服务器,否则RPC调用会中断,因为现在客户机和服务器需要不同长度的数组。这可能特别棘手,因为客户r可能只拥有客户端或服务器,并且无法同时升级两者

    但情况会变得更糟。假设客户端在某个文件中将
    Person
    对象写入磁盘。如果他们决定将Person序列化为简单的数字列表,则新技能将导致反序列化代码失败。更糟的是,如果您在枚举中重新排序技能,反序列化代码可能工作正常,但给出了错误的答案


    我喜欢选项3的原因正是因为您命名的原因:以后您可以添加更多功能,并且可以安全地这样做(好吧,除非您的客户使用该语言执行某些边缘案例)如果你想在不改变整个程序结构的情况下增加技能,我会考虑一些外部数据文件,你可以在不重新编译代码的情况下改变它。想想在一个真正的大项目中你想做的事情。选择技能的人可能是一个没有编程能力的设计师。他可以编辑TH。XML文件中的E技巧,但不是C++代码。 如果您用XML定义了这些技能,那么每种技能自然会扩展到存储更多数据。您的玩家也可以序列化为XML文件

    在运行时设置玩家技能时,可以根据XML文件中的技能名称构建一个哈希表。如果枚举玩家技能比查询玩家是否具有特定技能更常见,则可以使用字符串向量


    当然,此解决方案将比枚举解决方案占用更多内存,运行速度也较慢。但是,除非您的程序中有数百万玩家,否则此解决方案可能已经足够好了。

    如果您想经常添加技能而不使用