基于敏捷开发的数据结构研究
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.2 开发过程与方法

2.2.1 面向对象的界面接口设计

可视化编程环境提供了丰富的可视控件,大大简化了界面设计的难度,但编程者容易陷入过程化设计的泥潭,我们根据面向对象的思想,让界面与实现分离。

根据分析设计界面类,界面类成员主要由可视控件构成,根据简单原则,主要选用表格控件来显示简单变量值的变化、数组的值的变化及系统工作栈的变化,另设置一个图像控件用来显示图形,并设置“开始”命令按钮完成演示类的生成,对演示类进行初始化。“开始”命令按钮还完成如下功能:检查演示的输入是否合法,调用算法执行类,完成算法的执行过程,并产生脚本文件。“单步”执行按钮调用演示类的解释脚本行功能,实现算法的过程模拟与演示。另外,利用计时器控件可以实现自动演示,这只要在timer事件中调用单步执行即可。

2.2.2 迭代与重构

演示类的主要功能就是以行为单位从文本文件中读取脚本行,对脚本进行解释。核心模块用来实现对脚本的解释功能,这在开发的过程中不可能一次就设计好,需要在开发中不断迭代和重构逐步完善。

对指针类型需要用图示方式进行演示,结点类型有多种情况,从线性链表到广义表再到二叉树,它们的相同点是都有两类域,不同点是域名不同,通过迭代和重构,模拟内存分配,我们分别设计出结点的申请、释放和对域的赋值三个方法。最终形成以下方法:

procedure newnode(vname: string; fn: integer);

//按结点结构分配内存单元,vname为指针变量名,fn为结点域数

function getadd(vname:string):integer; //返回vname所指结点的行号

function getfieldvalue(vname: string; fn: integer):string;

//返回vname所指结点的fieldname域的值

procedure setdatavalue(vname: string; fn: integer; value:string);

//设置vname所指结点的fn数据域的值,并图示

procedure setpointvalue(vname: string; fn: integer; value:string);

//设置vname所指结点的fn指针域的值,并图示

procedure cleargraph; //清除图形显示区

procedure initmemo; //初始化指针类型的内存数据

procedure freenode(vname:string); //释放结点

procedure ptop(pexp,qexp:string); //指针值传递

procedure drawnode(i:integer); //在图形区显示地址为i的结点

procedure drawarrow(x1,y1,x2,y2:integer); //显示指针的指向

procedure setnewnodexy(x,y:integer); //设置下一个结点的位置

经过迭代与重构,系统的架构已经清晰,利用模板设计模式,在类型说明中设置一个关于演示类demo的类引用说明:ttdemo=class of demo,在选择了执行类的目录后,由类名生成具体的子类。把演示类的基类中不能实现的方法说明为如下所述的抽象虚方法:

function runprogram(no:integer):boolean;virtual;abstract;

//为在子类中执行选定算法的程序产生脚本

function inputok(no:integer):boolean;virtual;abstract;

//根据不同算法的要求进行输入合法性检查

procedure drawspecial(tobj:timage;s:string); virtual;abstract;

//把图形控件对象和特殊显示字符串传给子类,在图形显示控件对象上绘制具体图形

2.2.3 测试驱动

测试是一种验证行为,更是一种设计行为。在开发软件的初期,编写脚本可以起到测试用例的作用,在以后的重构中,都要使以前的脚本通过才可以。在开发过程中,可以结合自动测试工具和基于脚本的可视化实现自动测试。另外,测试用脚本还能起到使用说明文档的作用,始终记录最新的变化。

2.2.4 开发过程的线性化

敏捷开发强调开发过程的线性化,即使到了开发后期工作进度也不会减慢,工作内容也不会变得越来越大而无法完成。在本软件的开发中,一旦完成了演示类,后面的工作是在基类的基础上进行继承和扩展,对前面代码只在合适时机进行重构,能随时集成及运行。新增的类都可基于以下模板编写代码:

ex = class(demo)
private
    f: text;
public
    function inputok(no:integer): Boolean; override;
    procedure outprogram(no:integer);//输出算法演示文本
    function runprogram(no:integer): Boolean; override;
    //在此处可以增加一批新的要演示的算法执行程序
end;