【发布时间】:2011-01-15 07:38:26
【问题描述】:
假设你想写一个俄罗斯方块克隆,而你刚刚开始计划。
你如何决定什么应该是一门课?你是让单个块成为一个类还是只是不同的块类型?
我问这个是因为我经常发现自己写的课程太多,或者写的课程太少。
【问题讨论】:
假设你想写一个俄罗斯方块克隆,而你刚刚开始计划。
你如何决定什么应该是一门课?你是让单个块成为一个类还是只是不同的块类型?
我问这个是因为我经常发现自己写的课程太多,或者写的课程太少。
【问题讨论】:
退后一步。
我怀疑你在这里本末倒置。 OOP 本身并不是一件好事,它是一种有效解决问题的技术。问题如下:“我有一个由程序员组成的大型多团队组织,他们拥有不同的技能和专业知识。我们正在构建大型复杂软件,其中许多子系统相互交互。我们的预算有限。”
OOP 非常适合这个问题空间,因为它强调抽象、封装、多态性和继承。这些中的每一个都在多团队编写大型软件空间中运行良好。 抽象允许一个团队使用另一个团队的工作,而无需了解实现细节,从而降低沟通成本。 封装让一个团队知道他们可以对其内部结构进行更改以使其变得更好,而不必担心影响另一个团队的成本。 多态性降低了使用给定抽象的许多不同实现的成本,具体取决于当前的需要。 继承 允许一个团队以另一个团队的工作为基础,干净利落地重用现有代码,而不是花费时间和金钱重新发明它。
所有这些东西本身并不好,而是因为它们在大型团队复杂软件场景中降低了成本。
他们会降低单人软件场景中的成本吗?我不认为他们这样做;我认为他们会增加成本。继承的重点是通过代码重用来节省时间;如果您花更多的时间来获得完美的继承层次结构而不是通过代码重用节省的时间,这不是净赢,而是净损失。与所有其他人类似:如果您没有很多不同的实现相同的东西,那么花时间在多态性上是一种损失。如果你没有任何人会使用你的抽象,或者没有任何人需要你保护你的内部状态,那么抽象和封装就是成本,没有相关的好处。
如果你想做的是以 OO 风格编写俄罗斯方块来练习这种风格的写作,那么请继续前进,不要让我阻止你。我只是说:不要觉得你有道德要求使用 OOP 来解决 OOP 不适合解决的问题; OOP 不是万能的软件开发风格。
【讨论】:
我会制作一个基类 Piece,因为它们每个都有类似的功能,比如向右移动、向左移动、向下移动、顺时针旋转、逆时针旋转、颜色、位置等等。那么每件作品应该是一个子类,如 ZPiece、LPiece、SquarePiece、IPiece、BackwardsLPiece 等......你可能确实有很多类,但有许多不同类型的作品。
您所询问的 OOP 的重点是继承。当涉及到左/右/下移动等某些功能时,您不想重新发明轮子,也不想在多个位置重复精确的代码。这些函数不应该根据片段而改变,所以把它放在基类中。每个部分的旋转方式不同,但它位于基类中,因为每个类都应该实现它自己的版本。
基本上,所有部分的共同点都应该在基类中。然后,使作品独一无二的一切都应该在班级本身中。是的,我认为制作一个积木类并且每块有 4 个有点多,但有些人会不同意我的观点。
【讨论】:
对于俄罗斯方块克隆,我会说创建一个块类并使用enum 或类似的方法来记录它的形状会更好。原因是所有积木都以相同的方式运行 - 它们会下落,它们会通过更快地旋转或下落来响应用户输入,并且它们使用碰撞检测来确定何时停止下落并触发下一块。
如果每个块类型都有一个类,那么每个类之间的差异就会很小,以至于浪费时间。
在另一种情况下,你有很多相似的概念(比如许多不同类型的动物等),每个子类型都有一个类可能更有意义,如果子类型都是从父类继承的彼此不同
【讨论】:
取决于您的开发方法。
假设您使用敏捷,那么您可以从编写您认为需要的类开始。然后当您开始填写实现时,您会发现有些类已经过时或需要拆分其他类。
假设采用更多的先设计后构建方法(dsdm/rup/waterfall...),那么您会想要基于“用户故事”进行设计,请参阅 SwDevMan81 的链接以获取示例。
【讨论】:
您可能想查看How do you design object oriented projects?。公认的解决方案是一个好的开始。我也会买一本design patterns 的书。
【讨论】: