将程序分成多个类为什么很好?[关闭]


62

我仍然是一名高中学生(正在读10年级),并且还没有在学校学习实际的计算机课程。到目前为止,我所做的一切都是通过书本。这些书教会了我诸如继承的概念,但是将程序分成多个类又有什么帮助呢?这些书从未告诉过我。

我问这个问题主要是因为最近有一个项目。这是一款街机视频游戏,就像有人所说的Flash游戏一样(尽管我不知道Flash游戏是什么)。事实是,这只是一堂课。仅使用一个类,它就可以很好地工作(但是偶尔会有一些滞后)。所以,我只是问如何将其拆分为多个类会有所帮助。

这个项目是用Java编写的,我是唯一从事该项目的人。



49
当您阅读书籍时,它们分为章节吗?我们将程序划分为类来组织事物,就像书籍将文本划分为章节来组织事物一样。
riwalk 2012年

12
罗马人曾经说过:划分与侵占。
Giorgio 2012年

7
@Giorgio:还是用英语,因为不再使用拉丁语:Divide And Conquer
Matthieu M.

40
考虑到您已经在10年级,并且已经能够提出一个聪明的问题,提供所有必要的详细信息以获得良好的答案,提供背景信息和您的相对经验,以及提供背景信息,帮助您提出问题;您已经比我目前与之合作的许多人更胜任...
CaffGeek 2012年

Answers:


71

最简单的答案是,如果将所有内容都放在一个类中,那么在编写新代码时就必须立即担心所有事情。这可能适用于小型项目,但对于大型应用程序(我们正在谈论成千上万的线),这很快变得几乎不可能。

要解决此问题,您可以将功能分解为各自的类,并封装所有逻辑。然后,当您要在该类上工作时,无需考虑代码中正在发生的其他事情。您可以只关注那小段代码。这对于高效工作是非常宝贵的,但是如果不处理庞大的应用程序,就很难理解。

当然,将您的代码分解成更小的片段还有许多其他好处:代码更具可维护性,可测试性,可重用性等,但是对我而言,最大的好处是它通过减少代码量使可管理大量程序需要一次考虑。


7
仅当您在团队中处理相对较大的项目时,编程中的许多概念/想法(OO原理,分布式源代码控制,编码标准)才有意义。您将了解为什么在实际从事此类项目时会遇到麻烦。
joshin4colours 2012年

40
值得注意的是,将项目分解为多个类/文件并没有多大帮助。真正重要的是拥有独立的类,因此更改一个类不需要了解程序的其他信息(使用该类不需要了解如何实现该程序)。之所以提出这一点,是因为我经常看到带有很多类的代码,但是却没有真正的封装。封装是重要的部分-实现方式只是细节。
恢复莫妮卡2012年

2
一些关键词将是“耦合”或“解耦”,“封装”,“信息隐藏”。
marktani 2012年

@BrendanLong,我同意,我还要补充一点,封装几乎是不可能的。除非您当然要编写单独的程序……但是通常会有很多部分彼此不依赖,但是只有共享的依赖关系
So

29

好吧,最简单的回答可能是“它有助于组织事物”。如果没有其他问题,您可以将其与笔记本中的各个部分进行比较-如果此处“与UI相关的所有内容”和“与游戏性相关的所有内容”,则简单得多。

更为复杂的答案是,分配工作不仅方便,而且对管理复杂性也非常重要(而“管理复杂性”在编程方面几乎就是游戏的名称)。类或其他类型的模块使您可以“分离关注点”。您不仅知道在哪里查找“与UI相关的东西”,而且可以确定,如果要对UI进行更改,可以只在一个位置进行更改,而不必担心“现在,这是将字体设置为Comic Sans 的唯一位置吗?”。您可以进行更改,并且知道更改的影响仅适用于任何适当的(较小)范围。如果所有内容都在单个类或模块中,则基本上所有内容都是全局的,

在作为软件模块类型的类的特定情况下,还存在与类相关联的许多行为,并且大多数面向对象范式的开发人员发现将有意义的名称与分组相关的类相关联非常有帮助。一起发挥作用。所以,你可能不会实际上有一个UI类,你可能有一个Button类。与面向对象的类设计相关联的是一整套知识和技术,这是在主流编程中组织大型系统的最常见方法。


12

这是一个很好的问题!简单又好问。好吧……对于正在学习计算机科学且可能不了解OO且可能没有经验的学生而言,答案不是那么容易理解。

因此,我可以通过描述一个场景并使您想象多类软件比单片软件(仅由一个类制作)更好来回答:

  • 可读性:与几个小而有组织的文件相比,在具有10000行的文件中浏览和编写代码要困难得多。
  • 可重用性:如果编写单个类,则可以进行代码重复。这意味着更多的代码行和更多的错误(!)
  • 可测试性:测试单个功能怎么样?如果您将一种逻辑功能隔离在一类中,那么您的生活将会更加轻松。
  • 代码的可维护性:您可以在一个位置上使用多个类来修复错误或增强功能:漂亮的小类。
  • 项目结构:噢,您能想象一个只有一个源文件的项目会出现多么丑陋吗?

我喜欢您的回答,并且做了一些更改(仍然需要进行同行评审)。我想念的一点是更容易检测到SVN / GIT等软件版本控制系统中的更改。在一个项目中与多个程序员并行工作也更容易。
马丁·托马

我要说的是,关注点分离,内聚和去耦是一个比OOP学科更大的概念。命令性,逻辑性和功能性程序员都在努力实现高内聚和低耦合。
2016年

8

这里有很多好的答案,我当然同意他们的观点,但是我觉得还有更多值得一提的东西。

正如您所说,目前,您正在独自进行项目。但是,将来有时您需要在团队环境中工作。在那段时间里,您将分散工作(大概项目会很大)。结果,有几个(我猜真的是两个主要的)不同的选择。您可以具有一个文件的多个副本,然后处理文件的各个“部分”,然后通过复制和粘贴将它们“组合”起来,然后进行修改,以便各部分可以一起工作,或者可以完全拆分这些“部分”轻松地进入不同的班级,并讨论如何编写这些班级,并利用这些知识继续前进。

仍然需要将所有单独的部分集成在一起的工作,但是维护起来会容易得多。因为x文件包含y代码,而这就是您需要修改的代码。这是大多数其他答案都谈到的组织问题。

手持程序。来自乔治的链接


1
+1:团队合作也很重要!参见例如paulgraham.com/head.html和标题为“没有多个人编辑同一段代码”的段落。
Giorgio 2012年

@Giorgio我只是略读了一下,但看起来像是很棒的资源!我将其添加到我的答案中只是因为某些人可能没有在评论部分中查找。一定要给它更详尽的阅读时间。
Sephallia 2012年

这也适用于版本控制-在单独的文件上工作意味着更少的冲突和合并。
恢复莫妮卡

7

实际上,您所做的就是重新发明了过程编程。请注意,以这种方式编写软件很有可能,而编译器可能不会在意。多年来一直是这种方式,直到计算机变得更快,工具变得更好为止。

话虽这么说,但如果将代码分解为不同的逻辑单元(类,模块等),则可能会产生很多简短易懂的代码。以后可以维护。我的许多模块不到20行代码。我知道给定主题上的所有代码都在特定的位置。这也意味着,如果其他人加入该项目,他们将可以更轻松地找到事情。

正如Gerald Sussman所说,应该首先编写我们的程序,以便人们可以阅读,其次才可以使计算机运行。(如果您还没有读过“计算机程序的结构和解释”,则应该这样做)


4

一个使用多个类,因为当您进入更多的东西时,您会发现,当一大堆代码时,根本无法跟踪所有内容。

您只需要分而治之即可处理它。


3

面向对象编程是我在编程中见过的唯一的最佳想法。但这并不是在所有情况下最好的事情,您需要一点编程经验才能明白其中的要点,而且许多人声称在不使用OOP时会这样做。

如果您可以查找“结构化编程”,则可能会发现更直接有用的内容。(确保您阅读了有关旧的结构化编程的知识。旧术语通常具有新的,更奇特的含义,并且您还不需要花哨的任何东西。)这是一个非常简单的概念,可以将程序分解为子例程,这比将其简化为子例程要容易得多。将其分解为对象。这个想法是您的主程序是一个简短的例程,它调用子例程(Java中的“方法”)来完成工作。每个子例程仅知道其参数所指示的内容。(这些参数之一可能是文件名,因此您可以作弊。)因此,查看子例程/方法的标题可以使您快速了解其功能, 几乎一目了然。

然后,将所有子例程类似地分解,直到几行代码没有任何方法调用即可完成工作。一个主程序,它调用几个方法,每个方法都调用几个方法,每个方法都...。这样,您可以查看大型程序(或小型程序)的任何部分,并快速了解其功能。

Java是专门为编写面向对象的代码的人设计的。但是,即使是最严格的OO程序也使用一些结构化的程序,并且您始终可以颠覆任何语言。(我在普通C语言中执行OO。)因此,您可以在Java中执行SP或其他任何操作。忘记类,而将重点放在可以分解为小型可管理方法的大型方法上。我应该补充一点,SP可以帮助您重用代码,还可以使用DRY(google,但它意味着“不要重复自己”)原理。

希望我已经解释了为什么以及如何在不引入“类”的情况下将代码分成多个部分。它们是一个好主意,只是游戏的东西,而Java是OOP的好语言。但是最好知道为什么要做什么。让OOP独自一人,直到它对您有意义为止。


0

好处之一是可重用性。程序基本上是将一堆指令分组在一起。您会发现其中一些指令也适用于其他程序。

假设您制作了一个跳跃游戏。稍后,当您决定制作大炮游戏时,您会发现在跳跃游戏中使用的物理计算在这里很方便。

因此,您无需将其重新编写,也不必将其复制并粘贴到新程序中,而是将其放入一个类中。因此,下一次您制作另一款游戏时,游戏机制需要物理性,您就可以重复使用它。当然,这被过分简化了,但我希望这是有道理的。


0

首先,请注意,我是C ++和Python,而不是Java,因此其中某些功能可能不太适用。如果我对类在Java中的工作方式做出一些不正确的假设,请纠正我。

实例化类时,它们主要是有用的。没有实例创建的类实际上只是一个美化的名称空间。如果您以这种方式使用所有类,那么实际上,将事物从名称空间移到名称空间的好处似乎微不足道-最多,您会获胜,因为每个类中都包含一些私有数据并因此将内容进行了一些封装。

但是,这不是类发光的地方。考虑一下String类:使用char数组和一些静态函数可以拥有所有相同的功能。至此,功能为您提供了一些额外的安全性和语法优势。您可以写string.length()而不是length(char_array); 这不是什么大不了的事,但是很多人仍然喜欢它。而且,您知道如果有人给您提供了String,它是使用String构造函数创建的,并且必须与length函数一起使用-如果数组版本不能处理某些字符,那么它就无法阻止您将其放入其中。

仍然不是。关键是类将数据和对其进行操作的函数捆绑在一起,然后将它们全部抽象掉。当您有了一种方法时,void f(Builder b)您知道会得到Builder,并且可以预期它会支持某些行为。但是,您对数据或正在执行的功能一无所知-实际上,在编写和编译时,这两种定义都可能尚未编写f

因此,首先要了解的是,类使传递数据很方便,同时确保数据不会损坏。第二点是,对象具有的数据和功能(实现)都与对象有关,而不仅仅是您可以从其类型中分辨出来。


0

整个构想基于名为“ 分而治之”的一般规则。
这种范例几乎可以在任何地方使用。您将一个问题分解为较小的问题,然后解决了这些小问题,简单问题和众所周知的问题。
将您的程序划分为类是近十年来开始变得普遍的划分类型之一。在此编程范例中,我们通过一些对象对问题进行建模,并尝试通过在这些对象之间发送消息来解决问题。
有人可能会说这种方法更容易理解,扩展和调试。
虽然有些人不同意:)


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.