代码设计优秀编程实践

在过去的几节课中,我们已经看到了一系列工具为帮助我们创建procedures用于计算大量的计算processes。在我们继续讨论更复杂的计算问题之前,有助于退一步思考并且看到在创建procedures的程序处理中看到更通用的问题。特别是,我们希望花一点时间讨论好的编程实践。这听起来有点像讲授“母性和苹果派”,有点像谈论那些看起来明显,明显和无聊的事情,因为每个人都理解并接受它们。然而,令人惊讶的是,有多少“有经验”的程序员没有执行好的编程实践,我们希望让你获得正确的轨道。

因此,在本讲中,因此,在这节课中我们将简要地讨论创建procedures的几个方法方面:设计代码组件,在代码运行不正确时调试代码,为代码编写文档以及测试代码。我们将重点介绍每个阶段的一些标准实践,并说明为什么这些实践能够高效有效地生成代码。

让我们如何去设计代码的问题开始,给出一个问题的陈述。有很多方法可以做到这一点,但其中大部分都涉及以下几个步骤的组合:

•数据结构的设计

•计算模块的设计

•模块之间的接口设计

一旦我们制定了这些阶段的总体设计,我们会遵循通过创建实际组件的特定实例。我们还没有谈到计划中的数据结构,并将在几个讲座中回到这个问题。就我们这里的目的而言,要注意的关键是,在设计计算系统时,决定应该将哪些类型的信息自然而然的组合在一起,然后创建执行该分组的结构,同时保持与结构的接口细节的隐藏。例如,一个人自然地认为向量是x和y坐标的配对。人们希望能够在需要时摆脱坐标,但在许多情况下,人们自然会认为作为一个单元操纵向量。同样,可以想象将一组向量聚合在一起形成一个多边形,并且人们可以想象将多边形作为一个单元来操纵。因此,设计计算系统的关键阶段是确定系统的自然数据结构。

设计计算系统的第二阶段是决定如何最好地将计算分解成模块或片。这通常是一门科学也是一门艺术,但是有一些通用的指导方针可以帮助我们分离出设计中的模块。例如,是否有部分问题定义了可能多次使用的计算?是否有部分问题可以根据其行为进行概念化?例如,他们如何将某些输入转换成某些类型的输出,而不用担心如何完成这些细节。这是否有助于我们专注于计算的其他部分?或者说有点不同,是否可以根据角色识别计算的一部分,并在整体计算中考虑这种角色,而不必知道计算的细节?

如果可以的话,这些计算部分对于分离模块来说是很好的候选者,因为我们可以专注于它们的使用,而忽略它们如何实现计算的细节。

最后,给出一个能被识别的数据结构,信息将被操作;并且计算阶段,信息被改变;人们想要确定模块之间的整体信息流。每个模块需要什么类型的输入?每个模块返回什么类型的数据?如何确保正确的类型被提供,并按正确的顺序?在设计计算模块之间的整体流程时需要解决这些问题。

通过思考一个例子可能更容易被看到 - 事实上,你已经看到了一个这样的例子,我们实现了sqrt。当我们实施我们的平方根方法时,我们实际上参与了许多这些阶段。自从我们只是对数字感兴趣,我们并不担心数据结构。但是,我们确实花费了一些努力来分离模块。记住我们的基本计算:我们从猜测开始;如果足够好,我们就停下来;否则,我们通过平均当前猜测值和目标数与猜测的比值来做出新的猜测,并继续。

为了设计这个系统,我们分离出了几个模块:平均概念,测量“足够好”的概念。我们看到,其中一些模块本身可能依赖于其他程序抽象;例如,我们特定版本的“足够好”需要使用绝对值过程,尽管其他版本可能不会。

一旦我们分离出了这些不同计算的概念:average和good-enough,我们考虑了整个模块的信息流。请注意,我们可以将每个过程都视为黑盒抽象,这意味着我们可以专注于使用这些过程,而无需设计每个过程的具体实现。

 那么这些模块之间的流程是什么呢?在我们的案例中,我们从猜测开始,并进行测试,看看它是否够好。如果是的话,我们可以停下来,然后返回猜测值。

如果不是,那么我们需要平均目前的猜测和我们的目标数与猜测的比值。

然后我们需要重复整个过程,将这个新值作为我们的新猜测。

布置这些模块或黑盒的重点是我们可以使用它们来决定如何划分代码,以及如何隔离使用procedure的细节。正如我们在实现sqrt procedure时看到的,我们可以改变procedure细节,例如average,而不必更改使用该特定程序的任何程序组件。此外,模块之间的信息流动有助于指导我们创建procedure集。

 因此,当遇到任何新的计算问题时,我们想要尝试进行相同的练习:排除那些可以很容易分离的计算块;识别每个组块的输入和输出; 并通过系统列出信息的总体流程。然后,我们可以分别实现隔离的单元,并测试整个系统,同时隔离每个单元的影响。

你可能感兴趣的:(代码设计优秀编程实践)