Closed. This question is off-topic。它当前不接受答案。












想改善这个问题吗? Update the question,所以它是用于堆栈溢出的on-topic

7年前关闭。



Improve this question




我正在做一个简单的项目来管理桌上游戏的数据,但是我主要是用它来获得有关正确编码的经验。

我刚刚到达了五个紧密相关的类的地步,我不确定是将整个原样保留还是重构。

我所拥有的基本上是这样的:
  • ShipTemplate:该类(与c++模板无关)具有所有常量成员,并且包含有关Ships类别的基本信息。
  • TemplateSet:此类包含当前可用于构建的所有ShipTemplate,并且具有名称。它应该是独立的,因为它可以随时代表每个播放器的可用技术,因此一个人可以在不同时间保存/加载不同的音乐集。
  • Ship:此类表示完整的船,带有加载,名称和其他内容。它包含对ShipTemplate的const引用,该类不允许更改,以引用其基本功能。它可以扩展ShipTemplate,但是我想跟踪哪些Ships具有特定的底层ShipTemplate,并且这样做似乎更容易。
  • Fleet:此类包含Ships列表,具有名称和其他信息。它的成本变量应等于其中所有船舶成本的总和。
  • Deployment:此类包含指向玩家可用的所有Ships,Fleets和TemplateSet的指针。它还需要跟踪不再可用的ShipTemplate,但仍由已构建的Ship使用的ShipTemplate。它应包含等于玩家可获得的所有飞船费用之和的费用变量。它必须管理船舶从一个舰队到另一个舰队的转移。它必须找出哪些船在给定的舰队内,或者哪些船具有给定的ShipTemplate。

  • 不幸的是,每个类(class)都与其他类(class)交织在一起。我考虑过不同的方法,但是我不确定哪一种方法是正确的。
  • 在各处使用friend语句,这样,如果一个类修改了某些内容,则它可以正确更新所有其他类。
  • 使用很长的名称,例如Deployment::modifyShipThrustInFleet,并仅允许通过Deployment类进行任何修改,这将处理所有事情。
  • 删除TemplateSet和Fleets并在Deployment中表示它们,以便它可以正确更新成本值/指针而不破坏任何“正确性”规则。这也意味着对系统的每次修改都必须通过Deployment。
  • 将指向上层类的指针插入到下层类中,因此例如在更改Ship中的某些内容时,它可以自动更新其Deployment和Fleet的成本。

  • 还有其他我未曾见过的解决方案,或者可以重构成更多的类来帮助我获得可读的,可维护的代码?

    最佳答案

    只是一些想法。

    当以面向对象的方式进行思考时,对现实生活中的对象的思考会提出 View ,您应该在程序中进行描述。现实生活中的对象是什么?它是具有某些功能并公开某些功能的“事物”。

    例如ShipTemplate是船的蓝图。它应该定义大小,布局,零件类型和数量(DieselEngine,SteamEngine,AntiAircraftGun,UnderwaterMines等),以及它们如何相互连接。

    另一艘船是根据蓝图建造的-它应该具有所有实例。例如,它可能有两个DieselEngines和三个AntiAircraftGuns。没错,这艘船不是从蓝图继承而来的。蓝图仅是对船舶的描述,而不是其母公司。

    现在,每种类型的对象(蓝图,零件,船)都有其自己的属性和功能。例如,每个发动机消耗一些燃料,并且可以将船的速度提高到某个值。为什么不具有具有这些功能的Engine基础类? (遗产)。枪支也是如此(我们称其为ShipWeapon)。地雷枪与高射枪之间当然会有很大的区别,但是它们都是枪,都可以安装在船上,都具有重量,弹药类型,装弹时间,弹药容量以及是否在使用中。

    因此,这些是对象的一些属性。功能如何? OO设计的另一个重要概念是,每个对象都有(封装的)一些可以用它完成的功能(它可能会或可能不会更改对象状态)。例如,ShipWeapon应该具有Fire()方法,该方法可能应减少其中的弹药数量。或者先尝试使用Aim(sometarget)进行定位。另一方面,引擎将具有Start(),Stop(),SetSpeed(speed)。请注意,这些将在对象及其状态内部进行工作。船可能具有SetCourse(方向,速度),这将以所需的功率启动发动机并确定方向 Helm 的方向。另外船可能有Colide(船)。和Hit(typeofattackinggun),它会遍历船的所有部分并随机损坏一些(并为枪设置IsOperating或关闭其中一台发动机等)。

    如您所见,在设计面向对象的方法时可以涉及很多细节。知道何时停止也很高兴-程序真正需要多少细节(或准确性)。

    而且,可能会有一个全局世界,它将拥有所有船只。等等..

    程序的另一部分是基础架构。如何管理数据对象(船舶,世界,玩家),它们如何相互了解和交互。例如,可以通过全局 map 观察作为对象的每艘船,并且每艘船将通知其运动(观察者模式)。否则全局世界将基于全局时钟在某些时间间隔查询每艘船的状态。要么...

    我想我要说的是坚持主要的OO原则-封装,继承,多态性。那里有很多关于面向对象设计,设计模式等的文献,这很有用。 Wiki entry有点“学术”,但有主要定义,使您认为:)也请查看SOLID

    PS。通常,在一个类中完成所有操作通常是不良设计的标志。

    10-06 10:22