OOP-Tetris的哲学设计问题

时间:2009-12-07 22:12:05

标签: oop

您正在用Java编写俄罗斯方块程序。您将如何根据以下方面设置课程设计?

  • Piece class:有一个Piece类,内部数组决定了作品的形状,而不是七个Piece类,每个类一个。它们都是一个通用Piece类的子类。
  • 片断类表示:拥有4个Block个实例的数组,代表一个方块,每个Block包含其在棋盘上的位置(图形化)坐标)与有一个4x4数组,其中null表示那里没有阻塞,位置由数组的形状决定。
  • 位置Block数组或Piece数组中的每个Board都会将其位置与Piece和{{ 1}}了解构成它们的Board的位置。
  • 生成一块:拥有Piece类Blocks的静态方法,或者使用getRandomPiece创建一个具有PieceFactory的实例实例上的方法。
  • 操作当前篇幅:使用genRandomPiece模式,以便需要访问它的所有内容只使用代理,或者在{{Proxy上使用getCurrentPiece方法1}}类,并且在你想用当前作品做任何事情的时候调用它。

这不是作业。我只是对我的大学里介绍CS课程的内容不和,我想看看人们普遍认为的是什么。什么被认为是“好”的OOP设计?忽略这是一个介绍课程的事实 - 怎么做?

4 个答案:

答案 0 :(得分:10)

首先,我不会继承Piece类,因为它是不必要的。 Piece类应该能够在不使用继承的情况下描述任何形状。恕我直言,这不是继承的内容,它只会让事情复杂化。

其次,我不会将x / y坐标存储在Block对象中,因为它允许两个块存在于同一位置。 Piece类将保持一个网格(即2D数组)来保存块对象。 x / y坐标将是2D数组的索引。

至于获取随机片段的静态方法vs工厂对象,我会使用工厂对象,因为工厂对象可以被模拟用于测试。

我会将该板视为一个大的Piece对象。 Board类将大Piece对象保留为成员变量,并且可以保留其他Piece对象,例如正在播放的当前片段,以及要播放的下一个片段。这是使用组合来完成的,以避免继承。

答案 1 :(得分:3)

  • 一个Piece接口,有七个类为各个部分实现该接口(这也将使OOP课程能够讨论接口) (< strong>编辑:一个Piece课程。见评论)
  • 我会有一个BlockGrid类,可以用于任何块的地图 - 包括棋盘和单个棋子。 BlockGrid应该有检测交叉点的方法 - 例如boolean intersects(Block block2, Point location) - 以及旋转网格(课程的有趣讨论点:如果Board不需要如果rotate()方法位于BlockGrid,则要轮播。对于一件作品,BlockGrid代表一个4x4网格。
  • 我会使用方法PieceFactory创建getRandomShape()以获取七种形状之一的实例
  • 为了操作这件作品,我将进入模型 - 视图 - 控制器架构。模特是片。财务主任可能是PieceController,也允许或禁止合法/非法行动。在屏幕上显示该片段的事情是PieceView (hrm,或者BlockGridView是否可以显示Piece.getBlockGrid()?另一个讨论点!)

有多种合法方法来构建此。讨论适用于该问题的不同OOP原则的专家和协议将有利于该课程。实际上,将它与非OOP实现进行比较和对比可能会很有趣,它只使用数组来表示板和块。

编辑: Claudiu帮助我意识到BlockGrid可以充分区分各个部分,因此不需要具有多个子类的Piece接口;相反,Piece 的实例可能与基于其BlockGrid的其他实例不同。

答案 2 :(得分:3)

  
    

所有这些类和东西......它可能会使问题变得过于抽象而不是真正的问题。许多不同的方式来表示俄罗斯方块(stackoverflow.com/questions/233850 / ...)和许多不同的方法来操纵它们。如果它是一个介绍课程,我不会担心OOP。只是我的意见,不是你问题的真实答案。

  

话虽如此,只需一个Board and Piece课就足够了。

Board class :封装一个简单的2d矩形数组。像currentpiece,nextpiece这样的属性。常规如draw(),fullrows(),drop()等等。它们操纵当前的棋子和填充的棋盘方块。

Piece class :封装一组无符号16位数字,用于编码各种旋转的片段。您可以跟踪颜色,当前位置和旋转。也许有一个例程,rotate()是必要的。

其余的,取决于环境,处理键盘事件等......

我发现将过于强调设计往往会让人们忘记他们真正需要做的就是让某些东西运行。我不是说不设计,我说的往往是,让事情发展更有价值,让你有动力继续前进。

我想说,在课堂上,你有X个小时为俄罗斯方块游戏制作设计。然后他们需要转入那个设计。然后我会说,你有X天的时间,根据你上传的设计运行某些东西,甚至基于设计。

答案 3 :(得分:2)

片类:我认为所有片段的单个课程就足够了。类函数通常足以适用于任何部分,因此不需要子类化。

Piece Class Representation:我相信4x4阵列可能是更好的方法,因为你会发现旋转它更容易。

位置:位置绝对应该由电路板存储,而不是存储,否则您必须通过整个块来确保没有两个块处于相同位置。< / p>

生成一块:老实说,对于这个,我觉得它不会产生太大的差别。话虽如此,我更喜欢一个静态函数,因为这个函数实际上没有那么多它保证自己的类。

操作当前篇:我只是实现一个getCurrent函数,因为我觉得不需要通过添加额外的类来作为代理来使问题过于复杂。

我就是这样做的,但是有很多不同的方法,最后要关注的只是让程序运行。