【问题标题】:Best practices of creating Model class of MVC创建 MVC 的 Model 类的最佳实践
【发布时间】:2020-07-12 14:38:12
【问题描述】:

我要创建一个自己的扫雷游戏版本,我想知道,创建一类手机游戏的最佳方法是什么?

我有两个版本:

1.

class GameCell: UIButton {
    var bombCountAround: Int = 0
    var isBomb: Bool = false
}

2.

class GameCell {
    var bombCountAround: Int = 0
    var isBomb: Bool = false
    var button: UIButton!
}

OOP 和 MVC 编码哪个更好?

【问题讨论】:

    标签: ios swift oop model-view-controller


    【解决方案1】:

    如果您在 ViewController 中创建这些GameCells,我认为GameCell性质是一个接受用户交互并响应更新游戏板的按钮。所以我会说第一种方法似乎更合理。

    但是,如果您在模型中创建 GameCells,然后使用它们来创建 UI,我相信您可能会使用类似于第二种方法的方法,但您的 GameCell 应该是您的 Button 的属性。

    【讨论】:

      【解决方案2】:

      我不会推荐这两种模式中的任何一种。

      一个模型应该没有任何视图引用(即它应该没有 UIKit 引用)。您不想将视图(您在屏幕上看到的按钮、图像、镀铬等)和模型(整个棋盘的抽象表示,表示哪些方块有炸弹,哪些没有,哪些方块)混为一谈方块仍然被隐藏并且已经被取消隐藏)。

      FWIW,我个人也倾向于将bombCountAround 保留为由Board 为给定行和列计算的属性。它实际上并不是任何给定方格的属性,而是各个方格之间的关系。从理论上讲,您可以拥有一个属性来捕获它,从而不必在运行中重新计算它,但是查看周围八个单元格的计算开销非常小,因此真的没有必要。


      举个例子,我可能在棋盘上有一个特定方块的对象:

      struct Square {
          var isBomb: Bool
          var isHidden: Bool
          var hasUserFlagged: Bool
      }
      

      这个模型代表了我们在开始创建视图时需要了解的有关单元格的所有信息。具体来说,方块是否真的是炸弹,方块是否仍然隐藏(例如用户根本没有点击它),或者用户在那里放置了一个标志来表示他们认为那里是否有炸弹.

      顺便说一句,请注意我没有在模型名称中的任何地方使用Cell,因为这通常表示 UIKit 对象,例如集合视图单元格。模型不应该担心视图的实现(即,您是否使用集合视图单元格,或者只是堆栈视图中的按钮,或者只是带有约束的图像视图)。而Cell 暗示了一种视觉元素,而不是板上的抽象方块。

      话虽如此,我们可能想要一个结构来代表所有这些方块的整个棋盘,也许是一个代表整个游戏棋盘的Board

      struct Board {
          private var squares: [[Square]]
      
          init(width: Int, height: Int, bombCount: Int) {
              // build the squares array of array of `Square`, setting a certain number to have bombs
          }
      }
      
      extension Board {
          func isBomb(column: Int, row: Int) -> Bool {
              // look up to see if the `Square` at that row and column is a bomb or not
          }
      
          func howManyBombsNear(column: Int, row: Int) -> Int {
              // calculate how many nearby bombs there are
          }
      }
      

      现在,这可能不是正确的模型。也许您想将炸弹所在位置的初始设置与游戏时间统计信息(用户未隐藏的内容和带有标记的内容)区分开来。这取决于你。

      但要传达的信息是模型应该完全没有任何与视图相关的类型。视图完全从模型中抽象出来,因此您可以根据需要为相关平台实现它(例如,您的非 Catalyst macOS 目标可能使用与 iOS/iPadOS/tvOS 目标完全不同的视图集)。

      【讨论】:

      • 非常感谢!这对我来说是非常有用的答案!我只有一个小问题,如何连接 UIButton 的实例和这个模型(Square)?最好的方法是什么?
      • 控制器会这样做。因此,当游戏开始时,您将创建 Board 模型,并且您的视图控制器将添加与之关联的所有按钮。每次用户点击一个按钮时,您的控制器都会说“好的,让我们看看模型,看看我应该做什么来响应点击与板中特定行和列相关联的特定按钮。”
      • 知道了!非常感谢!
      猜你喜欢
      • 2018-01-31
      • 2019-04-16
      • 1970-01-01
      • 2011-02-04
      • 1970-01-01
      • 1970-01-01
      • 2011-09-22
      • 1970-01-01
      • 2015-09-11
      相关资源
      最近更新 更多