唯一不变的就是一直在变”--“数据”的华丽“变身术”
系列文章索引:
[WCF邮件通信系统应用 之 数据同步程序 之 设计内幕 之 一]
同步一个数据库要发多少个数据包?
[WCF邮件通信系统应用 之 数据同步程序 之 设计内幕 之 二]
"开门待客"还是“送货上门”?
[WCF邮件通信系统应用 之 数据同步程序 之 设计内幕 之 三]
“设计应对变化”--实例讲解一个数据同步系统
[WCF邮件通信系统应用 之 数据同步程序 之 设计内幕 之 四]
唯一不变的就是一直在变”--“数据”的华丽“变身术”
1,“唯一不变的就是一直在变”
“唯一不变的就是一直在变”--记不清楚这句名言是谁说的了,也许是从牛顿运动定律推导出的:)
来到这里的看客应该都是跟IT相关的人士,IT变化之多,变化之快是不用多说的了,对于我们这些从事软件开发的人来说,最害怕的就是这个“变”字:
需求改变;
设计改变;
代码改变
... ...
现在,我们为了缩短“变化的距离”,索性不要“设计”了,这样需求改变可以直接到代码改变,最近我们推崇“敏捷”,敏捷开发,敏捷过程,敏捷实践,敏捷到了1天1个迭代,需求变更的太快了,哪里还有时间谈设计?甚至,还有人大声高呼:“设计已死”!
对于1天1个迭代的开发模式,我也看不出设计有啥用,但是对于1个星期,1个月有可能有重大变更的情况,我建议还是有设计来应对变更,就像我之前的几篇文章,“设计应对变化”,至少,有设计,需求改变在设计这里得到了验证,得到了缓冲,而不至于直接上代码,累的半死,结果劳而无功,成不了英雄,却成了炮灰。
2,两种数据同步方案
回到我们的这部讨论数据同步的系列文章,我们来看看做一个数据同步系统应该做成什么样子:
方案1:将数据直接导出数据包,用邮件发到客户那里,然后导入;
方案2:将数据映射成数据实体对象,采用邮件系统作为通信的通道,就像采用HTTP通道一样,客户端接收到实体对象,最后导入数据。
方案1只需要5天(2人=10人天)而且有原来的代码可以参考;方案2可能要30人天但却是全新的方案没有现成的方案和代码可以参考。
假设系统的环境在以后发生了下列变化:
1,目标数据库对应的表增加了某些字段,这些字段是业务系统需要的不能同步;
2,将源数据的某一个表导入到目标数据库的另外一个表,这两个表内容相似但结构却不相同;
3,数据的发送方式不用邮件了,改用FTP或者其它方式;
4,由于目标数据库和源库在一个网络了,不想用数据包导入了,效率太慢
5,除了在“源系统”和“目标系统”直接同步数据,还想同步一点其它东西,比如业务对象
... ...
可以肯定,方案1永远只能做原来的数据同步,需求稍稍改变就得改代码,最后代码越来越复杂,最后没有人能够维护...
方案2非常方便的适应了新需求,运行良好,需要修改的代码非常少。
对于两套方案,你选择哪个?
作为项目经理,多半是方案1,它成熟简单,至于下个项目要用数据同步,那是下一个项目经理的事情,拿方案1去修改吧。
作为产品经理或者研发经理,方案2有可能衍生出一个新的技术解决方案(产品),而且它的可重用性很强,可以应对以后各种项目类似的需求。
既然写本篇文章,方案1的具体实现细节就不讨论了,我们来看看方案2中的数据,在系统中是怎么样变化,系统又是怎么样适应未来的变化的。
3,“数据同步”之应用架构
先看下数据同步系统的应用架构图:
数据同步系统分为数据发送端和数据接收端,
在数据发送端,数据的“变化过程”如下:
1,使用ORM框架,从数据源查询出数据到数据实体对象中;
2,数据实体对象经过“消息转换”组件,转换成系统消息对象;
3,将系统消息对象放到邮件消息对象中(可能需要压缩编码等辅助工作);
4,使用邮件发送组件,将邮件消息对象发送到数据接收端。
在数据接收端,数据的变化过程跟发送端恰恰相反:
1,使用邮件收发组件,将邮件消息对象接收到消息队列;
2,从邮件消息中取出系统消息对象;
3,使用“消息转换”组件,获得数据实体对象;
4,使用ORM组件,将数据实体对象存储到目标数据库中。
4,由数据同步系统到ESB
从上面的应用架构图中我们看到,系统大致分为3部分:
1,数据处理子系统,包括数据源、目标数据库,ORM组件,数据实体对象;
2,消息处理子系统,包括“消息转换”组件,系统消息对象;
3,邮件通信子系统,包括邮件邮件消息对象,邮件收发组件,邮件服务器;
整个系统的3大子系统都是独立的,其核心在于“消息处理”子系统,从应用扩展来看,我们很容易想到以后系统可以扩展为如下结构:
A:业务处理子系统+消息处理子系统+邮件通信子系统;
B:业务处理子系统+消息处理子系统+WCF / FTP子系统;
C:业务处理子系统+消息处理子系统+消息总线
方案C,是不是很像我们常提起的ESB(企业服务总线)吗?我们由一个设计方案,很顺利的扩展出N种新方案,这就是“设计的魔力”,谁说设计没用?
也许,你会觉得我“哗众取宠”,这些设计算啥啊,只是概念而已,项目有需要大伙加加班一样可以很快搞出来,还是看不出设计有啥用。你要是这么说请给本文一个“鸡蛋”,不用给“鲜花”了。
5,数据的“华丽”变身
我们先看看系统中的类关系图,看看数据是怎么变化的:
第1变:由数据表到实体对象
在本系统中,数据不在是单纯的数据,而是对象,对象本身就是封装数据和操作数据的方法的,系统使用PDF.NET数据开发框架将数据映射到了对象中,这样的对象称为“实体对象”,对于我们习惯的“数据表”而言,这是它的第一次变身;
第2变:由实体对象到消息对象
对于单纯的数据处理系统,将数据表映射成实体对象已经足够了,但是我们的设计目标是系统不仅仅只是处理数据的,至少,我们需要有“反馈对象”告诉我们数据的处理结果,“命令对象”告诉我们该怎么样处理其它问题,而这些对象是不能够直接跨越两个局域网的,需要把它放到邮件或者其它地方,来和其它系统完成通信。所以,系统要求有统一的“消息对象”,方便系统内部和系统间交互数据和调用功能、服务。
在这里,所有的其它对象到消息对象的转换都是通过“消息处理”组件完成,其中,实体对象到消息对象的转换使用了PDF.NET数据开发框架内置的转换类,将实体对象序列化成高效的二进制数据。
第3变:由系统消息对象到邮件消息对象
在步骤2中,转换的都是普通的系统消息对象,经过该步骤的转换,系统间已经可以正常交换消息了,但要把它通过邮件发送出去,还得有几个处理过程,编码,加密,压缩,处理成最适合邮件系统处理的消息格式,最后使用邮件收发组件将邮件消息对象发送出去或者将邮件消息接收下来,存入邮件消息队列。
至此,我们由普通的数据,变成了普通消息对象,再到邮件消息对象,完成了我们的“华丽变身”,我们的数据不再是单纯的数据了,它变成了对象,能够适应各种变化的对象。也许这个过程没有那么直接,甚至效率会有一点点影响,但它能够应对各种可能的变化,能够让我们以统一的对象思维模式来考虑问题,现在,你问我这个系统干了什么,我的回答是:
“将对象由一个系统同步到了另外一个系统”,
而不是
“将数据从A库同步到了另外一个局域网中的B库”。
所以,我们的系统应该改一个名字,不是现在的“数据同步系统”,而应该是“对象同步系统”。
- ML中相似性度量和距离的计算&Python实现
- ASP.NET MVC Model元数据及其定制: Model元数据的定制
- 小白也可以操作的手机TensorFlow教程:Android版和iOS版
- PhalApi-PHPExcel基于PhalApi的PHPExcel拓展
- [喵咪软件推荐(2)]全球服务器测速工具speedtest-cli
- 使用Keras创建一个卷积神经网络模型,可对手写数字进行识别
- 新生代的垃圾回收:Copy GC之基本原理
- [喵咪软件推荐(1)]全球国家信息库
- 一文教你在Python中打造你自己专属的面部识别系统
- [喵咪Liunx(6)]Nginx日志分析工具goaccess
- 用Atomic实现锁
- [喵咪Liunx(5)集群管理利器pssh
- synchronized关键字的语义
- [喵咪KafKa(3)]PHP拓展See-KafKa
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 图像处理笔记(8)---- OpenCV 获取追踪对象的HSV值
- (数据科学学习手札95)elyra——jupyter lab平台最强插件集
- Python 序列化/反序列化自定义类型
- Windows10下使用VS2017编译和使用yaml-cpp库
- CentOS7下编译yaml-cpp库
- SAP Spartacus CurrentProductService返回的null对象
- SAP Spartacus产品明细页面用Observable显示产品名称
- 关于rxjs里operators filter和map的详细讨论
- 用代码查看SAP Spartacus购物车内的行项目
- rxjs的map和switchMap在SAP Spartacus中的应用
- 用代码查看SAP Spartacus购物车内的行项目
- rxjs fromEvent的用法
- Python2和Python3的区别简单总结
- Django操作数据库
- Hive元数据服务MetaStore