小弟第一次在博客园发博,请大家多多包涵,多多指教
最近学到一种可以将DFD图(数据流图)转成SMS图(软件结构图),再转换成伪代码的方法
按照这种方法,就可以将DFD图“机械”转换为伪代码,而且得到的 结果唯一
(本人对软件工程认识不是很深,有些专业词语用错的话,还请大家多包涵包涵)
废话少说,开始
假设有一张 DFD图
里面有N个 加工 和 数据流
那么我们先将这个DFD图进行一定格式的排布
首先找到最长路径
那么我们就将最长路径的每一个节点作为 一层
一层的意思就是...
这样就分好层了
下一步是为 加工 和 数据流编号
规则是 从上到下 从左到右
方式是: 加工用数字 数据流用字母(超过26个用AA、AB等)
其中,数据流会穿插2个层,所有以左边的层优先
编号如下
上面的图除了编号外,同时做了 输入 主加工 输出 的划分
红色方块为主加工模块,左侧为输入区,右侧为输出区
划分方法则是,先标记每层的 数据流入加工的最大条数 和 数据流出加工的最大条数
(如第二层,有加工 2 、 3 ,总输入有2条,总输出2条,但是最大条数仍为1)
之后选择 输入条数和输出条数 跳变最大 的层 为主加工模块
当完成上面步骤 DFD图 的处理已经完成,开始转换 SMS图
首先说一下SMS图的结构
大框架如上图:
最左侧是输入,顶部中间位主加工模块,右侧为输出
转换的顺序是从输入开始
按照 输入 左深度优先 原则开始转换
左深度优先 即为 从 输入源头 找到一条最长的路径到达主加工,如下图
然后用 GET 表示输入流
MAKE INTO 表示 加工过程
PUT 表示输出流
1号加工可以表示为
其中 模块之间的 连接箭头表示 调用
(这里可能没看过UML或者这样的图的人会有点别扭, 其实你把箭头看成一个钩子,把需要调用的模块勾回来使用,这样应该能转过弯)
有圆点的箭头 表示 数据的流向
上图的 代码 大概是:
Var B
B = Fun(A);
Return B
(上面 MAKE A INTO B C 中并没有出现 C ,这个等下解释)
有人会问,上面的 B 是返回值,那为何 还是 GET B 而不是 PUT B 呢?
因为 B 是一个中转 ,即是下一层的 PUT 又是上一层的 GET
所以就规定,在 输入 中,如果发生 GET 和 PUT 和冲突,则取 GET
如果在 输出 ,那么 就取 PUT
懂了转换规则,下面就好办了
但是要记住
输入 的 转换是 深度优先的 而且 需要按这个顺序转换完后才能再向下进行
(这个图有错,就是调用线的数据流向有几处没有画上,请家大注意)
第一条深度转换完成, 还要注意的一点是,模块的位置
GET A 和 MAKE A INTO B C 是在一个层级上的, 而且GET A在左
GET B 和 MAKE B INTO D 也是一个层级上的
这一点要注意
然后 以此类推, 直到将输入的 路径全部转换完成
(上图依然有错,也是数据流向没有话,大家注意啊)
可以观察一下层级
之前的 MAKE A INTO B C 中没有出现 C
那么现在 C 模块出现后,就应该不上关系
从输入边界 连接到 主加工模块的时候,要多小心小心
输入 完成后,就到了 输出 了
输出 仍是 深度优先,找出最长的路径
输入 是从 图纸的最右边画起
画法和 输入的画法是一样的 只是 GET 变成了 PUT
MAKE I J INTO K 这里需要补上 J
最后得到一个完整的图
而且在层级关系上,需要对齐一下
上图是关系对齐之后的 SMS 图,可以发现,主加工就是红色部分
GET F
GET E
MAKE E F INTO J G
PUT J
PUT G
让他们这几个模块对齐 ,而又不能失去之前的层级关系(如 E 模块,被提升了一个层级,但是他的输入,仍然是和 B 一个层级的
到处 DFD图,转换为 SMS图完成
下面就是伪代码了
这样标记之后的 SMS 图已经可以看到伪代码的影子了
我们需要先给 SMS图 再次编号
规则是:
输入 深度优先
输出 广度优先
转换伪代码的工作就是 按顺序 ,将模块上的 代码写下即可!
得到:
GET A
MAKE A INTO B C
GET B
MAKE B INTO D
GET D
MAKE D INTO F
GET F
GET C
MAKE C INTO E
GET E
MAKE E F INTO H G
PUT H
PUT G
MAKE H INTO J
PUT J
MAKE G INTO I
PUT I
MAKE I J INTO K
PUT K
到此 DFD -> SMS -> 伪代码 的转换完成
小弟第一次在博客园发博,请大家多多包涵,多多指教