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

简介

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

主要的功能就是一个映射: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. 组合类型:以上各种类型的组合,例如互斥集合类型。

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

总结

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

时间: 2024-10-01 09:28:26

利用数据类型,简化程序逻辑的相关文章

Qt and C++ Reflection,利用Qt简化C++的反射实现

如何在C++中实现反射机制,应该算是C++开发中经常遇到的问题之一.C++程序没有完整的元数据,也就无法实现原生的反射机制.从性能的角度讲,这样的设计不难理解,毕竟在运行时储存这些元数据需要额外的开销.不为你不使用的东西付出代价,这是C++的哲学,所以当我们需要反射机制时,我们得自己来实现它.所幸如今各种C++的反射实现已经相当成熟,比如boost::reflect,以及本文所使用的Qt. Qt是常见的C++跨平台应用程序框架之一,除了用于开发GUI程序之外,Qt本身也是一套完整的C++库.不同

利用mysqlbump实现MySQL逻辑备份与恢复

mysqldump作为重要的MySQL备份工具,功能相当强大.备份参数.恢复策略,需要仔细研究. (1)基本语法 备份单个数据库或单个数据库中的指定表: mysqldump [OPTIONS] database [tables] 示例: 1.备份单个数据库mysql:mysqldump -uroot -p mysql > mysql.sql 2.备份单个数据库mysql的指定表user:mysqldump -uroot -p mysql user > mysql.user.sql 备份多个数据

如何计算一段程序逻辑运行时间?

-- 1 class Program 2 { 3 4 [System.Runtime.InteropServices.DllImport("Kernel32.dll")] 5 static extern bool QueryPerformanceCounter(ref long count); 6 [System.Runtime.InteropServices.DllImport("Kernel32.dll")] 7 static extern bool Query

[.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能

[.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能 本节导读: 上节说了缓存是以空间来换取时间的技术,介绍了客户端缓存和两种常用服务器缓布,本节主要介绍一种.NET中特别重要的缓布技术Cache.利用Cache提升程序性能. 1. 缓存Cache的命名空间 .NET中对缓存有两个命名空间 命名空间1:System.Web.Caching 命名空间2:System.Runtime.Caching 引用范围:这两个命名空间,都可以在Web和非WEB应用程序中

[.net 面向对象程序设计进阶] (18) 多线程(Multithreading)(三) 利用多线程提高程序性能(下)

[.net 面向对象程序设计进阶] (18) 多线程(Multithreading)(二) 利用多线程提高程序性能(下) 本节导读: 上节说了线程同步中使用线程锁和线程通知的方式来处理资源共享问题,这些是多线程的基本原理. .NET 4.0以后对多线程的实现变得更简单了. 本节主要讨论.NET4.0多线程的新特性——使用Task类创建多线程. 读前必备: A. LINQ使用  [.net 面向对象编程基础] (20) LINQ使用 B. 泛型          [.net 面向对象编程基础] (

利用OllyDebug查看程序调用的dll模块

最近在做一个Qt项目,在产品发布的时候一直为找不到程序到底缺少了哪些dll组件而困扰.具体问题是,在我的项目中使用到了QMediaPlayer播放一段音频文件,我使用的开发环境的Win7 32位,而在发布安装包的时候,还是照常去掉Qt相关的环境变量,然后运行可执行程序,提示缺少什么dll,我就向可执行程序的目录下拷贝对应的dll,直到程序可以正常启动运行.就是按照上面的方法,我制作了软件的安装包,但是,当将这个软件安装到XP系统上测试时,发现程序没有声音了,这个问题让我很纠结. 后来,我在网上找

JavaScript状态机程序逻辑编辑器

制作背景 之前做Win8 Metro动态加载内容框架的时候,由于采用了XAML+JavaScript的方法,程序复杂的执行逻辑是由JavaScript控制的,而页面一多,流程一复杂,制作起来就非常麻烦,还要考虑不同XAML页面返回事件的名称.所以就写了个状态机模型的程序制作工具. 技术支持 说到制作状态机,无疑微软的VS是最强大的,微软本身就有Workflow.使用微软的工作流就可以很方便的制作出一个状态机,然后在用System.Workflow下的类库提取,整理结构,然后生成JavaScrip

利用TensorFlow实现多元逻辑回归

利用TensorFlow实现多元逻辑回归,代码如下: import tensorflow as tf import numpy as np from sklearn.linear_model import LogisticRegression from sklearn import preprocessing # Read x and y x_data = np.loadtxt("ex4x.dat").astype(np.float32) y_data = np.loadtxt(&qu

小程序学习(四)小程序逻辑层之注册页面

小程序学习(四)小程序逻辑层之注册页面 注册页面(Page) 小程序页面的注册,是通过 Page()  函数来完成的.接受一个 object 参数,指定页面的初始数据,生命周期.事件处理函数等. object 参数的属性: 属性 类型 描述 data Object 页面的初始数据 onLoad Function 生命周期函数--监听页面加载 onReady Function 生命周期函数--监听页面初次渲染完成 onShow Function 生命周期函数--监听页面显示 onHide Func