为什么将程序代码和图形界面代码打包在不同的类中是最佳实践?


15

因此,我的老师告诉我,不要将程序代码和图形界面代码封装在同一类中,而要使其完全独立是非常重要的。我目前正在编写带有网格的iPhone游戏。对我来说,在同一个“网格”类中创建图形网格和技术代码更有意义。其他程序员会对此皱眉吗?保持图形界面和代码独立确实非常重要吗?如果不这样做会出现什么问题?

谢谢!

编辑:谢谢大家!我可以先编写项目,然后再复制代码以形成关注点分离设计吗?我知道这可能完全违背了这个目的,但是只是作为实践……所以下次我可以从头开始应用这种设计模式了吗?

Answers:


17

您的老师所指的概念是“关注分离”。

为了说明您的情况,请先完成程序,然后再决定将其移植到Android。与将网格逻辑分开分开相比,您将不得不重写更多的代码。

接口控件应该只关注绘制的内容,网格逻辑应该只关注网格中的内容,而不是如何绘制它。

这有帮助吗?


谢谢它的帮助。问题是,当我将两者封装在一个类中时,对我来说,最终产品的可视化要容易得多。这是否是我不遵循“关注分离”的正当理由?还是绝对有必要,我不能称自己为合适的程序员:p?

这种分离的积极影响是,如果您选择替换GUI,则不必重写游戏逻辑

@John-如果您需要可视化设计,请写一份规格说明文件。如果可以描述它,则可以开始将图形界面代码与游戏逻辑本身分开。
拉姆猎犬,

3
这也使网格代码更易于测试。测试GUI会很痛苦(由于环境可能会造成混淆),因此,使GUI成为可测试对象上的“显然正确的”薄薄层是一个巨大的胜利。(再次,这是关注点分离。)
Donal Fellows

1
@约翰:我们中的一些人通过做中学到最好的东西。假设这个项目没有那么大,请尝试将其作为一个类编写,并使其在iPhone上运行。现在将其移植到Android,跟踪“痛点”。最后,按照Russ C的建议重写它。我想您会明白为什么要分离逻辑和表示。
彼得·罗威尔

4

为了使更改代码更容易。如果明天您不想使用网格而是列表,该怎么办?当您的GUI与逻辑分离时,这很容易做到。

除此之外,您还将编写可重用的代码。如果您的GUI不包含您的技术代码,您也可以重复使用它。一次创建一个包含所有选项的精美网格,您可以在其他项目中使用它。混合使用GUI和技术代码将阻止您执行此操作。

它还为您提供了更易于阅读的代码。如果您的网格仅具有GUI功能,则更容易理解或更改您的代码。


3

面向对象编程将关注点分离的一般方法,其中代码被分离为逻辑任务。最初,这似乎需要更多工作。但是随着项目的增长,它使跟踪和管理代码变得更加容易。

因此,最好将负责显示网格的代码与处理可能在该网格中显示的数据的代码分开。



0

要以其他答案为基础并举一个例子,您应该以某种方式让自己将逻辑/数据注入到网格中,反之亦然。

您的网格控件可以公开一个Render方法或一个DataBind方法。

class GridControl
{
    public Render(GridData data) { ... }
}

要么

class GridControl
{
    public DataBind(GridData data) { ... }
}

然后,您的逻辑单元可以采用GridControl并将数据对象绑定到它,或者在每次发生任何更改时使用该数据对象手动调用render。

您的GridLogic还应该引用GridControl,以便它可以绑定到发生的任何输入/事件。

数据绑定背后的想法是,网格控件监视数据是否有任何更改并重新呈现自身,因为公开呈现功能意味着您的逻辑单元手动重新呈现控件。

无论哪种方式,您都可以通过这样拆分逻辑和网格的方式来更轻松地更改另一个,而不破坏任何内容。您也可以编写一个新的控件(如),ListControl以将数据显示为列表而不是网格,而不必重写所有逻辑。


0

我强烈建议您看一下MVC体系结构

这是对您所提到的概念(程序代码和图形界面的分离)的改进。MVC代表模型-视图-控制器。这里的Model是数据,View是图形界面代码,COntroller是处理数据的代码。

这样,您已经创建了程序的三个部分。每个部分都可以更换,而无需更改其他两个部分。


0

这取决于您预期会发生的未来更改的种类。您想要最小化的是正确实现每个单个功能更改所需的手动代码更改数量。

如果更改仅限于V部分或“视图”,则MVC胜出之处。

以我的经验,变更影响所有三个部分的可能性更大,因此最好不要将它们分开。为了说明我的意思,我长期以来一直使用一种称为“ 动态对话框”的技术,在该技术中,将一个新要求(例如“允许用户编辑名称,并在完成时执行XYZ”)作为一个单独的块输入到源代码中。文本:

if(deTextEdit(&sName)){
  // do XYZ
}

而不是进行多个单独的编辑,而是指定编辑字段存在,为其构成唯一标识符,将其绑定到模型变量并将其链接到失去焦点事件处理程序。

如果您转到该链接,您将看到一个更复杂的示例。

基本上,该想法是将代码转换为特定领域的语言,以便最大程度地减少实现目标的编辑次数。您这样做的原因不仅是要减少工作量,而且还要通过忘记或错误编码一个或多个编辑来减少引入错误的机会。它还将源代码的大小减少了大约一个数量级。

它不是免费的。它为程序员介绍了一次性的学习曲线。


0

图形界面取决于系统,而游戏核心是一种完全独立于其运行系统的算法。保留这两个功能将使程序更易于维护,测试和调试,因为一个子系统中的更改不会影响另一个子系统的工作方式。即使您不关心可移植性,我敢打赌您也关心程序的健壮性和可维护性。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.