面向对象跟结构化的区别与分析 按我的理解,所谓的面向对象就是就是在程序设计中按类来对系统进行设计。举个例子,要发广告邮件,广告邮件列表存在数据库里面。倘若用C来写的话,一般会这样思考,先把邮件内容读入,然后连接数据库,循环取邮件地址,调用本机的qmail的sendmail命令发送。 仔细的分析一下,就会发现这样的设计完全是从程序员实现程序功能的角度来设计的,或者说,设计类的时候,是自低向上的,从机器的角度到现实世界的角度来分析问题的。因此在设计的时候,就已经把程序编程实现的细节都考虑进去了,企图从底层实现程序这样的出发点来达到满足现实世界的软件需求的目标。类与类之间是通过发送和接收消息相联系的,接收消息的对象通过调用类的方法来实现相应的操作。访问限制符Private、protected和public将类分成三个部分:私有部分、保护部分和公有部分。使数据具有不同的隐蔽程度。类定义可包含一组构造函数和析构函数,构造函数保证了在声明类的对象时对其自动初始化,而析构函数则保证对类的对象正常地清除。从已有的类还可以派生瓣的类,前者称为基类,后者称为派生类,OO方法中继承的原则在这里得以体现。能够突破类的私有部分,禁止其它函数直接访问限制的友员机制,以及由运算符重载、函数名重载和虚函数构成的多形性,使程序员能以更自然、方便的表达方式实现对象的操作。 当然万事万物皆为对象,而对象又是类的实例,因此在面向对象的编程中,就如上面的例子,我们可以在分析三个大类的前提下,定义这些类的对象。大家都知道任何对象都会有 属性,方法,过程,函数,事件等,且类与类之间又可以继承,子类继承父类,子类间有多态性。类也可以先进行封装,再使用。这些都是面向的特性,当然它还有一个代码可重复使用的特性。也是因为如此,在程序设计中如果采用面向对象的编程方式可以更好的以人类的正常思维进行分析。至于具体的分析,到后面将用俄罗斯方块来分析。相比之下,传统的结构化程序设计则采用另外一种编程方式,它是采用按模块功能进行系统分析的,下面附出结构化方法的大概流程图。图略 结构化程序设计的主要思想是功能分解并逐步求精,当一些任务十分复杂以至无法描述时,可以将它拆分为一系列较小的功能部件,直到这些自完备的子任务小到易于理解的程度。例如,计算一个公司中每一个职员的平均工资是一项较为复杂的任务。可以将其拆分为以下的子任务 (1) 找出一个人的收入 (2) 计算总共有多少职员 (3) 计算工资总额 (4) 用职员人数去除工资总额 而计算工资总额本身又可以分为一系列子任务: (1) 找出每个职员的档案 (2) 读出工资数额 (3) 把工资加到部分和上 (4) 读出下个职员的档案 类似地,读出每个职员档案的记录又可以分解为一系列子任务 (1) 打开职员的档案 (2) 找出正确记录 (3) 从磁盘读取数据 具体看来结构化程序具有以下几个特征:自顶向下,逐步细化,模块化设计,结构化编码 从软件工程发展的历史来看,早期的软件开发量小,结构化程序设计在成功地为处理复杂问题提供了有力的手段。然而到80年代末,它的一些缺点越来越大。比如当数据量增大时,数据与处理这些数据的方法之间的分离使程序变得越来越难以理解。对数据处理能力的需求越强,这种分离所造成的负面影响越显著。并且对于每一种老问题的新方法都要带来额外的开销,与可重用性相比,这种编程思想显得落后许多。面向对象就是在这种情况产生了,相信在未来十年内,面向对象还将继续发展。 介绍完了两者大致的定义后,接下来用俄罗斯方块来分析一下两种编程思想具体的不同 对于结构化程序的方法,在这里用脚本语言javascript来描述,而面向对象则采用如日中天的java来分析。 首先按结构化编程方式来完成俄罗斯方块的话,我们会对问题按数据结构进行模块化的分解,本程序将用以下几个模块来完成: (1) 开始游戏(function beginGame()) (2) 俄罗斯方向键的控制(function keyControl()) (3) 块的消除(function decline()) (4) 面板的移动(function moveBar()) (5) 暂停游戏(function pauseGame()) (6) 游戏重新开始(function replayGame()) (7) 方块的显示(function randBar()) 在分解这几个模块后,就已经大致完成了对程序的整体分析了。这是对程序中问题的描述,接下来则是具体的算法分析,也是结构化当中的解决问题了。要解决本程序中最主要的一个算法一一方块的显示算法,在本程序中采用四维数组的方式来表达方块,比如: 1,0,0,0 1,0,0,0 1,0,0,0 1,1,1,1 这样则表示方块中的L形状态,其他则不在一一列出。其他算法的则略过。还是把重点转移到面向对象中来。 在面向对象中首要解决的是本程序中要分为几大类来完成最基本的系统设计。这个俄罗斯方块放在网页中,也就是采用applet小程序的形式,但由于java跨平台性,它可以在windows,linux,unix等操作系统中使用。本程序大致分为三个大类:Tetrisapplet,Brick3D,Board。下面是TerisApplet的UML图: TerisApplet Init() Initcomponent() Minewgameactionperformed() Miendgameactionperformed() (2) initcomponent():初始化窗口以及窗口中的组件 (3) minewGameActionPerformed():当选择菜单或者工具栏上的“开始游戏”命令后,开始新游戏。 (4) miEndGameActionPerformed():当选择或者工具栏上上的“结束游戏”命令后,结束游戏。 2.Brick3D,以下是UML图
3.Board Board类实现俄罗斯方块的主要大部分功能,下面是它的UML图
从建模图中可以看出:Board实现的方法有drop()、move()、reset()、newGame()、endGame()、run()、paint()、createNewBrick()、checkRow()、processKeyEvent()、processMouseEvent()、processMouseWheelEvent()等方法,这些方法的功能定义如下。 (1) drop():砖块的下落函数。 (2) move():移动砖块,1表示向右移动,-1表示向左移动 (3) reset():初始化board_info数组 (4) newGame():开始执行线程(游戏) (5) endgame():停止执行线程(游戏) (6) run():线程运行的函数 (7) paint():绘制背景,边界和砖块 (8) createNewBrick():创建下一个新的砖块形状、角度和颜色,角度、形状和颜色随机产生 (9) checkrow():检查是否可以消行,并计算分数 (10) processKeyEvent():处理键盘事件,控制砖块的移动和旋转 (11) processMouseEvent():处理鼠标事件,控制旋转和左右移动 (12) processMouseWheelEvent():处理鼠标滚轮事件,当向下滚动时,控制块向下移动 分析完后,本程序用了三个主要的类:Brick3D对象、Board对象和TerisApplet对象,分别对应Brick3D.java,Board.java和TetrisApplet.java三个文件,在实例中还包括了一个Html文件。 虽然用面向对象写的代码更多,看似面向对象更为麻烦,但实际上面向对象更能解决现在的软件工程问题,而结构化程序设计的方法只对小型的软件设计适合。未来十年内面向对象还是软件开发的主流。 |
|