TCP组件设计篇

        天下皆知美之为美,恶已;皆知善,斯不善矣。有无之相生也,难易之相成也,长短之相刑也,高下之相盈也,音声之相和也,先后之相随,恒也。是以圣人居无为之事,行不言之教,万物作而弗始也,为而弗志也,成功而弗居也。夫唯弗居,是以弗去。------《道德经-第二章》

        将《道德经》第二章作为该文的序,真的是一言难尽。“天下皆知美之为美”可以对应天下“程序猿”都知道到什么是好的软件设计,但是又有不同的认知,特别是别和C++人员讨论细节。最近发现C++人员会关心更加底层实现,而像我这样Java人员根据关心预留给业务人员的接口和实现方式。个人感觉关心的点不同,但是有时候会争吵,在这边特别推荐领域驱动设计,这里面就提到了解决方案。

        争执中,纠结中,郁闷中,烦躁中当这些过程都过去的时候,重要静下心来重新设计整体过程。

目标

       目标的产生也就是为什么要做TCP组件,某种场景直接使用TCP会比使用任何第三种组件要好很多(被人嘲笑为什么不使用MQTT等这些第三方现成的组件,我只能表示淡淡的一笑,其实这次里面写的很多功能MQTT其实已经包含了)。

        TCP组件的目标是统一处理内部的C++和Java之间的通信,并且需要解决身份认证功能(安全性),以及协议的解码器支持(JSON格式,XML格式,字符串格式,protobuf格式)。简单看看其实TCP组件功能不是不是很多,目标其实也很明确,不知道从什么时候开始这么简单的功能或者目标会变的那么复杂(这其实就是需求转换为软件设计的一个过程)。

验证

       当我们在选择一项开源组件或者一种自己没有使用过的内容的时候,对于像我们Java这种开发人员会参考网上一些信息作为参考,选择是否使用,又有多少人真正做过长达一个月或者更长时间的验证呢(这点其实完全取决于我们需要使用这种组件第三方哪些功能)?读取源码和了解他的设计思想也是你对这种第三方组件的认知和验证。

       本次我们需要验证的是SSL和protobuf,并不是我们认为SSL或者protobuf有什么不稳定因素,而是我们需要对它们有更加深层次的理解,就想使用Spring的人喜欢读取Spring源码一样,我们只是想更加了解它,而不是简单的使用。

选型(完全基于Java)

        Java的TCP服务端组件有很多,例如Netty,mina或者国内大神写的T-IO等都是很好的选择方向。本次选型选择了Netty,请不要问我为什么选择使用Netty(其实对于我这次定义的单机版本TCP组件,完全可以用原生的Socket),只是因为我在其他项目中使用过,对于Netty有着一定程度的理解。

       对于业务事件,本来想用RXJava订阅模式去处理的,但是因为个人不太喜欢RXJava的处理和编码习惯,所以选择Google提供的EventBus作为我的业务事件触发机制。

设计原则

       消息体定义规范(也就是说必须遵循,对于公司内部或者项目组内部而言其实这是一件简单的事)。

消息体格式模板

        Java读取Socket字节原则,不管是使用Netty或者mina以及自己写的Socket服务,对于在Socket服务读取来自Client端传输过来的数据的时候,不会直接转换为对象,将服务端读取数据的复杂度降低。服务端只是将数据转换为定义的简单对象。

消息体定义

       设计模式的使用,因为本次设计的是组件所有在本次开发中大量使用单例模式,策略模式,工厂模式以及事件驱动在代码中的体现(在这里插一句话,有时候不是只有组件开发或者应用框架才会使用设计模式,容许我吹一个牛吧,在之前的一个项目中,对于订单模块我使用了大量的设计模式,将订单可以进行任意的扩展,并且提供了大量的测试用例方法。不光光是单元测试也包括数据流测试。只是我当初提供了大量的UML,流程文档)。

预留给业务的接口

业务读取消息业务处理时间
JSON数据格式业务事件基类
XML数据格式业务事件基类
Protobuf数据格式业务事件基类
String数据格式业务事件基类

对于JSON转换为业务对象使用的是fastjson作为转换组件。

对于XML格式转换为业务对象使用的Java自带的JAXB。

对于Protobuf则使用google自带的转换com.google.protobuf.Parser类。

以上。

是否需要再来一点干货呢?算了吧。天已黑,夜已凉。洗洗睡吧。等我所有功能完成然后基于代码分享并且进行说明。

你可能感兴趣的:(TCP组件设计篇)