黄河笑 杨焕宇 陈海建 王 磊 郑任儿
摘要 :本文论述了在设计与开发“软件工程”网络课程中采用的基于案例的教学内容设计,该教学设计以同一个案例贯穿所有章节,增进了学生对知识点的掌握和理解;开发环境使用Dorado MVC架构(Struts+Hibernate+Spring),获得了好的效果。与传统的开发模式比较,这种开发模式最大的优势在于可以节省开发人员在开发Web应用表现层时的工作量,同时又为用户提供非常友好的交互界面。
关键词 :网络课程;案例;树型结构
中图分类号:G642 文献标识码:B
1引言
在开放教育和远程教育中,网络教学正被越来越多地使用,开发适用于网络教学的高质量的网络课程已经成为发
展网络教育的一个非常重要的课题。
《现代远程教育技术标准体系和11项试用标准(简介)》中对网络课程进行了定义。网络课程是通过网络表现的某门学科的教学内容及实施的教学活动的总和,它包括两个组成部分:按一定的教学目标、教学策略组织起来的教学内容和网络教学支撑环境。
“软件工程”课程是本科计算机专业的一门重要课程。在当前的教学中,特别是开放教育和远程教育中还存在着很多欠缺,案例太少,或者各章中的案例相互割裂,使得学生学完该课程之后无法形成整体的软件工程概念和思想。因此设计和开发贯穿整个教学过程的案例成为“软件工程”网络课程的必然选择。
2 “软件工程”网络课程的教学内容设计
2.1以案例为中心
当前的计算机相关专业实践教学环境存在诸多薄弱环节,特别是在软件工程教学中,很难为学生提供一个全面的感性认识。而当前的教学是离散的过程,没有提供一个完整的商业软件的实例来讲解商业软件开发的全部过程。经过调查研究、综合对比和专家论证,我们选择了某
软件公司的商务软件“应急系统”作为整个软件工程网络课程的案例。选择该软件的原因是该系统在Windows平台上基于C++开发,而C++是大部分计算机科学与技术专业的学生都学习过的第四代开发平台,不足的地方是部分学生不了解应急系统。在教学内容设计中我们先对此公司“应急系统”的相关知识作了简单介绍,然后把软件工程的各个阶段与该软件的相关内容进行了一一映射和组合,公开了大部分相关设计和源代码。
2.2兼顾面向过程和面向对象
当前软件设计与开发的手段一般采用面向过程和面向对象这两种方法。虽然“应急系统”是采用面向对象方法设计的,但是我们补充了面向过程的设计内容,这样学生通过比较,既能熟悉和了解面向过程和面向对象的设计方法,又增强了理解,从而获得了比较好的教学效果。
3网络课程支撑环境的设计
3.1总体结构
系统设计应由上而下进行。首先设计总体结构,然后再逐层深入,直至进行每一个模块的设计。总体设计主要是在系统分析的基础上,将整个系统划分为若干子系统,子系统则由若干模块组成。数据的存储以及整个系统实现等方面都进行了合理的安排。图1所示为“软件工程网络”课程开发与设计的总体结构图。
3.1系统开发平台——Dorado MVC架构
Dorado全称“Dorado Web应用开发套件”,包含:Dorado Web UI控件集及UI引擎(Dorado Web UI Components and UI Engine),Dorado可视化集成开发工具 (Dorado Studio),Dorado MVC开发框架和Dorado Web应
用框架。其中Dorado MVC开发框架的主要功能有:提供类似Struts的MVC开发框架,以便更加方便地利用Dorado套件进行基于MVC架构的开发;提供性能监控控制台,可以方便地对系统运行过程中各功能点的运行效率进行统计和分析;支持国际化资源配置;支持模块化配置。Dorado MVC开发框架是一个可选件。Dorado套件完全支持各种第三方开发框架,如Struts、WebWork等。我们利用Dorado与目前较为流行的Struts+Hibernate+Spring进行协同开发。
3.2系统主要模块算法与设计
(1) 集合混淆算法
客观题测试用于学生自测。题目是随机排列的,顺序与数据库的存储顺序不同,它使用了Java.util.Collections中的shuffle(Listlist)方法来实现,下面是其在JDK 6.0中的算法和代码。
使用指定的随机源随机更改指定列表的序列。所有序列更改发生的可能性都是相等的,假定随机源是公平的。
此实现向后遍历列表,从最后一个元素向前一直到第二个元素,将随机选择的元素重复交换到“当前位置”。元素是从列表中随机选择的,从第一个元素运行到当前位置。
此方法以线性时间运行。如果指定列表没有实现RandomAccess接口并且是一个大型列表,则此实现在改组列表前将指定列表转储到该数组中,并将改组后的数组转储回列表中。这避免了二次型行为,该行为是因为在适当位置改组一个“有序访问”列表而引起的。
private static Random r;
public static void shuffle(Listlist) {
if (r == null) {
r = new Random();
}
shuffle(list, r);
}
public static void shuffle(Listlist, Random rnd) {
int size = list.size();
if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
for (int i=size; i>1; i--)
swap(list, i-1, rnd.nextInt(i));
} else {
Object arr[] = list.toArray();
// Shuffle array
for (int i=size; i>1; i--)
swap(arr, i-1, rnd.nextInt(i));
// Dump array back into list
ListIterator it = list.listIterator();
for (int i=0; i it.next(); it.set(arr[i]); } } } (2)DES加密算法 由于客观题的随机排列,使得试题的排列次序与数据库中有所不同。同时,考虑到通过逐条在数据库中查询来校验答案对数据库的压力过大,所以事先查询出试题的答案,然后根据打乱后的试题次序把正确答案拼成一个字符串,然后加密放到页面的隐藏域中。这样一来,当提交试题查看结果时不用再次查询数据库,只要把答案字符串解密,然后分割成数组校验即可。
这里的加解密采用了DES算法。
DES算法的入口参数有三个:Key、Data、Mode。其中Key为8字节共64位,是DES算法的工作密钥;Data也为8字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。
DES算法是这样工作的:如Mode为加密,则用Key去把数据Data进行加密,生成Data的密码形式(64位)作为DES的输出结果;如Mode为解密,则用Key去把密码形式的数据Data解密,还原为Data的明码形式(64位),作为DES的输出结果。在通信网络的两端,双方约定一致的Key,在通信的源点用Key对核心数据进行DES加密,然后以密码形式在公共通信网(如电话网)中传输到通信网络的终点。数据到达目的地后,用同样的Key对密码数据进行解密,便再现了明码形式的核心数据。这样便保证了核心数据(如PIN、MAC等)在公共通信网中传输的安全性和可靠性。
下面是加密算法的部分代码(解密原理类似):
public class DesEncrypt {
private Key key;
/**
* 根据参数生成KEY
*
* @param strKey
*/
public void getKey(String strKey) {
try {
KeyGenerator _generator = KeyGenerator. getInstance("DES");
_generator.init(new SecureRandom (strKey.getBytes()));
this.key = _generator.generateKey();
_generator = null;
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 加密 String明文输入,String密文输出
*
* @param strMing
* @return
*/
public String getEncString(String strMing) {
byte[] byteMi = null;
byte[] byteMing = null;
String strMi = "";
BASE64Encoder base64en = new BASE64Encoder();
try {
byteMing = strMing.getBytes("UTF8");
byteMi = this.getEncCode(byteMing);
strMi = base64en.encode(byteMi);
} catch (Exception e) {
e.printStackTrace();
} finally {
base64en = null;
byteMing = null;
byteMi = null;
}
return strMi;
}
/**
* 解密 以String密文输入,String明文输出
*
* @param strMi
* @return
*/
public String getDesString(String strMi) {
BASE64Decoder base64De = new BASE64Decoder();
byte[] byteMing = null;
byte[] byteMi = null;
String strMing = "";
try {
byteMi = base64De.decodeBuffer(strMi);
byteMing = this.getDesCode(byteMi);
strMing = new String(byteMing, "UTF8");
} catch (Exception e) {
e.printStackTrace();
} finally {
base64De = null;
byteMing = null;
byteMi = null;
}
return strMing;
}
(3) 章节维护算法
本网络课程中的课程章节、目录均为树形结构,其数据模型采用了树的模型,然后通过递归从根开始逐层遍历显示每个节点,便于导航学生学习。
下面是显示树形结构的代码,由于树形结构的显示使用了ExtJs(Ajax)框架来渲染,所以代码最终将产生JavaScript代码的字符串,交由ExtJs框架完成最后显示工作。
public String getExtTreeString(String prexHref ,String target ,boolean allowEdit ) {
......
//查询根节点(包含子节点层次)
Course rootWithHierarchy = treeNodeDao. getTreeRootWithHierarchy();
StringBuffer rootInfo = new StringBuffer();
//构造ExtJs的树形代码
appendInfo(rootWithHierarchy , rootInfo);
StringBuffer treeInfo = new StringBuffer("new Ext. tree.AsyncTreeNode(" + Constants.PLACEHOLDER + rootInfo + ")");
return ExtUtil.formatExtStr(treeInfo);
}
private void appendInfo(Course node , StringBuffer buf){
if(node == null) return ;
//如果是叶子节点,构造叶子信息
if(node.getIsLeaf()) appendLeaf(node,buf);
//如果是目录,构造目录信息
else appendFolder(node , buf);
}
private void appendFolder(Course node , StringBuffer buf){
buf.append(",{text:'" + node.getText() + "',");
if(allowEdit){
buf.append("href:'"+prexHref+node.getId()+"',");
buf.append("hrefTarget:'" + target + "',");
}
buf.append("id:'" + node.getId() + "',");
buf.append("leaf:false,");
buf.append("children:[" + Constants.PLACEHOLDER);
//遍历子节点,构造子节点信息
for(Course child: node.getChildren()){
appendInfo(child , buf);
}
buf.append("]}");}
private void appendLeaf(Course node , StringBuffer buf){
buf.append(",{text:'" + node.getText() + "',");
buf.append("id:'" + node.getId() + "',");
buf.append("iconCls:'user',");
buf.append("href:'"+prexHref + node.getId() + "',");
buf.append("hrefTarget:'" + target + "',");
buf.append("leaf:true");
buf.append("}");
}
从上述代码中可以看出,首先找出(包含子节点信息的)根节点,然后通过appendInfo方法来产生ExtJs的JavaScirpt代码,appendInfo会根据节点类型(叶子或目录)来调用appendLeaf或appendFolder方法,其中appendFolder首先生成该目录的信息,然后逐个显示子节点信息,子节点又会调用appendInfo方法。就是这样递归的调用,形成了最终的字符串,然后通过服务器传到表现层,通过ExtJs来显示整棵树。
4结束语
我们在设计和开发“软件工程”网络课程时,采用基于案例的教学内容设计,同一个案例贯穿所有章节,增强了学生对知识点的掌握和理解。开发环境采用Dorado MVC架构(Struts+Hibernate+Spring),获得了好的效果。这种开发模式与传统MVC的开发模式比较,其最大的优势在于可以节省开发人员在开发Web应用表现层式的工作量,同时又为用户提供非常友好的交互界面。
从表1中可以看出,本文采用的方法在开发工作量、用户界面、软件可扩展性等三个方面都具有相当大的优势。
本网络课程的设计和开发是从教学内容和网络教学支撑环境两个方面展开的,已在教学中使用一年,收到了较好的教学效果。特别是课程章节采用树型结构,使得学生在自主学习的过程中获得了更好的导航效果,提高了学习效率。下一步的工作是多增加艺术性方面的内容,尤其是媒体素材设计方面。
参考文献:
[1] 林惠强,刘财兴,林丕源. “软件工程”课程启发式教学的研究与实践[J]. 计算机教育,2008(11):40-42.
[2] 佚名. Dorado与Strats、Hibernare、Spring的集成开发模式[EB/OL]. [2009-6-10].http://www.javaeye.com/topic/141135.