利用数据类型,简化程序逻辑

简介

最近对一段遗留代码进行了重构。这段代码看似简单,却花了我很多时间。现在记录下来一些主要的分析过程,以备参考。

主要的功能就是一个映射:string -> [int | double | string]. 接口如下:

  • get(name, result); // 如果name为预定义的,则得到一个结果
  • set(name, value); // 如果name为预定义的,将数据传入。

数据类型的变化

从功能描述可以看到,结果数据的类型是三个基本类型的联合结构(C++)。随着预定义名字的逐步添加,很快出现了新的数据存取要求。

  1. 枚举类型:例如set(”A”,1);与set(”A”,”ok”);效果相同。
  2. 结构类型:例如set(”A”,1);此时要求同时set(”B”,”hello”);set(”C”,0.5);…
  3. 别名类型:例如set(”A”,1);与set(”B”,100);效果相同。
  4. 集合类型:例如set(”A”,1);set(”A”,2);意味着set(”A”,{1,2});
  5. 互斥类型:例如set(”A”,1);意味着set(”B”,0);set(”B”,1);意味着set(”A”,0);
  6. 空值类型:例如set(”A”,NULL);意味着set(”A”,value);value依赖于name。
  7. 默认值类型:get(“A”, value);合法,即使没有调用过set。
  8. 强制值类型:如果set(”A”,1, FOREVER);那么”A”不能再设置任何其它值。
  9. 访问记次类型:如果set(”A”,value);”A”的访问次数加一,具体次数可以通过get(”A”,ACCESS)得到。
  10. 附加操作类型:可以设置一个钩子函数,执行附加操作.
  11. 组合类型:以上各种类型的组合,例如互斥集合类型。

原有的代码基于基本类型,使用了一套复杂的函数逻辑来完成。新的代码采用了明确的类型定义来完成,保持了这段程序的主要功能,即数据存取流程的简单性。

总结

通常我们会抱怨遗留代码中混乱的逻辑,但是不要忽视其中隐藏的功能需求,应该采用更简单的机制去重构,例如本文的数据类型机制。

 

posted @ 2015-06-12 13:55  yunfeng_net  阅读(162)  评论(0编辑  收藏  举报