Visual Basic.NET编程的设计思考

2008-01-14  来源:   浏览次数 4

  [前言:]本文中的程序设计是指程序的"设计"(program design),所强调的是设计,而不是一般文章中提到的编程(program)。

  本文的目的是学习如何把实际的编程问题概括为五个简单的步骤,以及在设计应用程序时如何以这五个步骤作为出发点。

  内容:

  · 算法

  · 五个编程步骤

  · 横向改进

  · UML

  · UML类图表

  在过去的很多年里,出现过很多的正式的程序设计方法学。在方法学中有些相对复杂,也有些相当简单。但是所有的方法学的目标是相同的:帮助程序员写容易编写、调试和维护的程序。

  本文从一个非常简单的设计方法学开始我们的程序设计讨论。尽管这个简单的方法学是相当基础的,但是它的目的是引起你思考程序的设计的问题。在你研究过这个简单的方法学后,我将介绍称为UML。UML是很流行的设计方法,特别适合面向对象编程。

  为什么烦恼?

  我在长期的教学中经常看到这样的问题,当我把要解决的问题分配给全班同学后,在几秒钟内就出现了鼠标和键盘的声音,因为学生们已经开始输入代码解决手头的问题了。但是,并不是所有的学生都是这样的,有一个学生拿出一张纸,并开始在纸上写一些东西。几分钟过去了,那个学生终于开始把代码输入计算机了。几乎没有异常,虽然该学生迟一些开始,但是他更快地完成了任务并且他的解决方案比班上的其他同学更好。为什么?

  如果你看到该学生在纸上写的东西,你会发现那是程序设计的问题。有些学生的设计相当精确,花费了数张纸,然而其它的设计相当简洁。但是重要的是这些学生有了程序的设计的思考。

  算法

  每个程序都需要有一个设计或框图供程序员遵循。用程序员的说法是每个程序需要一个算法。简单地说,算法就是解决特定问题的系统方法的描述。对于程序员来说,算法是蓝图或处方,我们遵循它来建立程序。

  宏观与微观算法的对比

  算法有不同的"风味"。我们可以谈论用于编写给定的程序的算法,在这个层次,我们是在宏观层讨论算法。该算法试图捕捉程序的一般状况而不是程序每个方面的详细情况。

  我们也可以在微观层讨论算法。在这个层次我们需要写下程序各个方面的信息。例如,如果数据在被使用前必须先排序,就有成打的排序算法供挑选。选择一个排序算法就确定了程序的一个方面。一旦你对数据排序后,你需要另一个微观算法来显示它。

  你可能会猜到,我们可以收集所有的微观算法来建立一个宏观算法。如果我们从微观算法开始并向上形成程序的宏观算法,我们所作的事情称为从底部向上(bottom-up)的程序设计。如果我们从宏观算法开始并向下形成微观算法,所作的就称为从顶部向下(top-down)的程序设计。

  那么哪种方法最好?如果你拿到了所有的关于哪种设计途径更好的文章并让它们首尾相连,你永远不能得到答案。每种方法都有优点和缺点。

  不管使用哪种设计方法,你都必须有一些程序的设计。至少你要有手头上的编程问题的描述和解决问题的计划。一旦了解了问题,你就能找出如何解决它。我看到了太多的因为用户和程序员没有就要解决的问题进行沟通而造成的失败。

  因为我相信对要解决的问题的可靠的了解是编程的第一步,而且是必需的一步。我可能更喜欢从顶部向下的程序设计方法。有了这种想法后,让我们使用宏观方法来观察实际的各种编程问题。

  五个编程步骤

  无论程序多么复杂,都可以被简化为五个基本的步骤。这些步骤是:

  1. 初始化

  2. 输入

  3. 处理

  4. 输出

  5. 清除

  下面我将更详细的介绍这些步骤。

  初始化

  设计程序时的初始化步骤是你必须思考的第一个步骤。初始化步骤包括在程序与用户交互前它必须做的所有工作。程序在与用户交互前执行一些操作似乎很奇怪,但是很多程序都是这样实现的。

  例如,我们都使用过微软Word、Excel或类似的程序。在这些程序中,你知道可以点击"文件"菜单选项并且在该菜单的尾部可以看到最近使用过的文件列表。它们不是靠魔术跑到这儿的。该程序可能从磁盘数据文件读取最近使用的文件列表并且把该列表加到"文件"菜单。因为该列表在程序为用户显示信息前就被读取了,就必须在初始化步骤中处理。

  初始化步骤的另一种普通的事务包括读取设置文件。这类设置文件可能包括查找某个数据库或其它磁盘文件的路径名称。根据程序的类型,设置文件可能包含显示字体、打印机名称和位置、前景色和背景色、屏幕分辨率等等。其它程序也许会读取网络连接信息、Internet访问和安全性特权、密码和其它的敏感信息。

  在你自己的程序中,你必须考虑程序在工作前必须有哪一些类型的信息。如果你的设计需要任何设置信息或预备信息,初始化步骤就可能是处理它们的地方。

  输入

  输入步骤一般是你期待的。它是收集输入程序的任何信息以完成事务的步骤。在大多数情况下,如果你仔细思考程序要达到什么目的,那么定义输入列表就是相当简单的。例如,如果你编写一个贷款利息程序,你就知道需要询问用户贷款的总金额、利率和贷款的期限。

  但是,在其它一些情形中,你必须思考应该让用户输入什么信息。例如,如果你编写一个地址薄程序,每次运行程序时,你真的要求用户每次都输入保存地址薄的磁盘文件的名称以及文件的位置吗?换句话说,有些输入步骤可以,也应该放入初始化步骤中。可以在初始化步骤中读取的信息量的种类依赖于程序的特性。但是,作为一条重要的规则,大多数用户希望重复的信息存储在设置或初始化文件中,而不是每次运行程序时重新输入。

  输入来自于何处是设计决定的。设置文件很强大,在可以用到的时候应该尽量使用。很明显,其它的输入信息只有在用户输入的时候才可能知晓,就象我们常作的利息示例程序一样。在这些情形中,一般使用文本框向用户收集要使用的信息。因为用户必须与文本框交互为程序提供信息,文本框、标签、菜单和其它程序元素的放置方法定义了程序的用户界面的重要部件。

  很多书本都说过如何设计有效的用户界面的。我没有办法评价其合理性。但是,它绝对不会伤害读完那些书的人。在本文中我谈到了很多用户界面设计的问题。

  处理

  处理步骤包含操作输入的信息以生成程序需要的结果。在贷款示例中,程序将接受输入(贷款量、利率和期限),把它们插入金融方程式中,解出方程式并输出想要的结果(每个月支付的金额)。处理过程接受输入,"压碎"它们,并产出问题的答案。

  注意处理过程一般不会在屏幕上显示任何信息,它的唯一的目的是操作数据生成结果。但是也有一条值得注意的例外。如果你事先知道处理步骤将花费很长的时间,为用户提供一些信息表明程序正在运行是一条好主意。我们运行的程序一般有一个过程条表明手中的事务已经完成的百分比。另一个普通的例子是在完成前提供剩余时间的估计。大量的基于Web程序使用这种方法,在这些情况中必须有一些反馈表明程序仍然在工作。但是,在处理步骤相当快的情形中,为用户显示信息一般没有作用。

  输出

  从某种角度来说,这是程序的最重要的目的:为用户提供他们希望解决的任何问题的答案。我们的示例程序中的很多在文本框中显示答案。例如,如果你编写一个程序计算每个月贷款的支付金额,输出步骤的所有工作是把金额显示在文本框中。

  但是,其它一些程序复杂得多。也许你运行程序从数据库中读取你的名字、地址、电话号码和其它的很多信息片断,接着把它们显示在屏幕上。这类复杂的程序可能需要成打的文本框来显示必要的输出信息。在有些情形中,在文本框中显示结果的效率不高。例如,使用grid或者list控件显示一个填充了客户数据的表可能更好。

  输出步骤中要重点注意的是向用户显示结果,因此它也是用户界面的一部分。前面你看到输入步骤是用户界面中的一部分,因为它从用户那儿收集数据。在输出步骤中,用户界面与用户交互的方式更被动,但是在设计的时候也必须考虑用户的需求。用丰富的方法为用户显示信息几乎是艺术的表现。

  清除

  在某个程序完成了事务后,使用清除步骤"温和地"关闭它。你可以认为这个步骤与初始化步骤相对应。尽管很多简单的程序可以简单地关闭而不需要做进一步的操作,但是有一些复杂的程序可能需要一些帮助。例如,如果程序在初始化步骤中读取设置文件初始化了一些变量,清除步骤一般会使用用户最新的信息更新设置文件中的这些变量。

  清除步骤一般与关闭磁盘数据文件(包括设置文件和数据库文件)相关。有些程序跟踪某个用户运行程序的时间并把这些信息写入日志文件。在日志文件中跟踪运行过某个程序的人的姓名、启动程序的日期和时间、停止使用程序的时间等并不罕见。

  另一种日志文件称为错误日志文件。错误日志文件的目的是记录程序运行时所遇到的任何错误的信息。程序员可以使用错误日志文件的内容帮助自己调试程序。

  清除步骤执行的实际事务依赖于程序本身。但是,有时候如果在初始化步骤中执行了一些操作,那么在清除步骤中也需要执行一些相匹配的事务。打开和关闭不同类型的磁盘文件就是这两步的普通的事务。

  每个程序都需要这五个步骤吗?

  所有的程序都需要这五个步骤吗?不。有很多示例程序不需要初始化和清除步骤。通常,初始化和清除步骤出现在很复杂的程序的设计中。

  如果你有一定的编程经验,那么就知道哪些程序需要所有的五个步骤哪些不需要。但是,你在接近程序设计问题时应该假定所有的五个步骤都是必须的。在后面的设计中丢掉某些步骤比在设计未完成前把它们放入设计中容易得多。

  横向改进

  前面我表明了我喜欢把从顶部向下的宏观算法作为程序设计过程中的出发点。最基本的是在解决某个问题前你必须了解问题。但是了解用于解决问题的微观问题的时刻也会到来。随着我们的处理从程序的概貌转到细节,我们在增加视图的细节,或者说粒度。另一种说法是,我们从一般移动到了特殊。

  我们能使用五个编程步骤作为设计过程的宏观视图的出发点。下一步,我们检阅每一步并提供每个步骤包含的更详细的信息。这个过程称为横向优化。有一个例子可以帮助我们了解这个过程。

  假定你有一个用户,他拥有一个保存所有用户职位的数据库文件。这些职位按照授予职位的日期排序,保存在数据库中。但是该用户希望按照字母次序(基于该用户遇到的某个人的名字)查看职位。让我们看一看如何使用横向优化设计一个解决方案。

  初始化步骤的横向改进

  我们已经知道该用户有一个职位数据库。我们也知道他希望有一个按名字的字母次序排列的列表。这是算法的宏观视图。

  既然这样,在初始化步骤中执行什么操作呢?很明显我们应该打开该职位数据库。在职位被排序后我们需要一个Visual Basic .net窗体显示结果。因为我们知道数据库位于网络上,并且当该用户启动程序时我们能知道用户的名称和密码,因此我们认为事务很简单。有了这些信息后,我们首先作的横向优化可能如图1所示。

共3页  1 2 3

相关主题:

网友评论