<转>如何架构、设计与实现高质量的远程接口

http://www.tech-q.cn/thread-7190-1-1.html 架构师之道:如何架构、设计与实现高质量的远程接口
一、【前言】
刚刚经历完一个公司的项目,涉及很多架构设计、远程接口。在使用(我们自身)平台设计的接口过程中十分曲折、全体痛苦,而我负责的传真接口却让外部客户(电信方)与内部客户(应用方)感觉愉快清晰而受内外好评。因此,我感觉颇有必要将我历来的设计经验分享出来,以帮助团队成长,未来的项目中少走弯路,作出成熟的、高质量的接口设计。
二、【正确的人,做正确的事】
任何优秀的架构师都明白的道理:
1、 需求永远是第一位的,接口为需求服务。需求是接口的“衣食父母”。
2、应用方(工程师们)也是另一种意义上的”衣食父母”,如接口架构不良、实现较差,难用难扩展甚至没人愿意用,则最终会被“父母”抛弃。
3、有时候,我们看似比“衣食父母”更专业、更有经验,但并不见得比“父母”更有“生活智慧”,不要去试图教训“父母”,或让“父母”适应你。相反,尽一切可能适应或满足“衣食父母”的需求才是正确的设计之道。
4、好酒也怕巷子深; 好设计需要好的媒介加以表达。写一份优良的接口设计文档,并在评审中清晰明白的阐述设计思路,是架构师的基本功
5、好酒是与好窖、好水、好温度、好酿酒师密不可分的(再加上一段时间)。 让团队成员尽可能广泛参与设计与评审,才能集思广益、查漏补缺,更能沟通顺畅、执行无误,切忌孤芳自赏、闭门造车、欲速不达
6、如果你的团队中的“木桶效应”非常明显。你需要做两件重要的事: 不要让自己的工作成为短板;尽可能补救那块最短的板
三、【人与制度】
人与制度的关系,就像人与自然的关系。 人能改变自然,但首先是被自然改变
优秀的设计背后一定有优秀的作者,但如果“自然环境”不良,好设计也难以诞生或容易夭折
如果你的团队一直不能诞生优良的设计,最大的可能只有两点: 人或自然环境相当不佳
具体到影响设计质量的制度建设上,我只 建议4点
1、 让你团队的最优秀者作独立设计师或主设计师,无论是产品设计还是架构设计
2、 需求评审必须严格且广泛参与,业务流程图(注意:不是PageFlow)与业务规则描述是产出物中的必备内容,可多轮直至全部细节都经过评审
3、 架构与接口设计的评审也必须同样不可省略,可多轮直至满足全部需求点(含潜在需求)方可通过评审
4、 接口的设计与现实最好由同一人负责,别推脱或假手他人,甚至让新人或实习生来开发接口的实现
四、【接口的协议与框架】
目前,最常见的远程接口协议是 基于HTTP协议基础上的soap、hessian、Json-RPC等。前两者,我应用已久,我对技术人员的协议建议是: hessian。对于Java开发者来说, 支持soap(webservice)协议的最好的框架类库是xfire(另一个是axis远不如xfire好用);而支持hessian协议的框架类库,最好的就是spring。因此, hessian+spring是我的推荐,也是很多架构师的不二选择。
五、【远程接口的架构设计】
比起协议与框架的选择来说, 接口的架构设计才是体现设计师真正水准的分水岭。
一般来说,无论远程接口还是本地接口,常常会有异步执行的情况: 即调用方call被调用方的接口,同步返回请求成功,但实际操作是被调用方延后去执行的。这种时候, 提供回调接口是最佳选择,只有万不得已之时,才考虑让调用方轮询被调用方的接口,以查询执行结果。
因此, 回调模式与轮询模式相比,无论是及时性、安全性、可靠性以及性能效率上远胜不止一筹。只有一种极特殊的情况下,我们完全无法采取回调模式:即被调用方的系统过于老旧,不可改造,无法回调不同的调用方。大多数时候,我们都可以用回调模式取代轮询模式,甚至可进一步做得更完美一点, 让被调用方对于调用方不存在直接依赖(答案我不直接讲出来,自己思考一下 怎么将<直接依赖>变成<优雅且万能的间接依赖>)。
架构方案也是综合技术能力的体现,需要设计者在协议规范、语言能力、面向对象思想、数据结构、设计模式等方面不能存在明显短板。记住: 一份出色的设计文档是你设计工作的最终载体
六、【远程接口的设计实现】
我列举一些易犯(特别是接口设计的新手)的常见问题:
1. 不定义接口类(interface),而是直接定义抽象类
2. 接口返回对象参差不齐,随便定义。
——最好 定义全局统一的Result对象:resultCode(全局返回码), resultObject
3. 异常处理非常不统一,有时候用CheckedException,有些时候用UncheckedException,有些时候用ErrorCode
——我的建议是 所有异常在方法内部捕获,统一在ResultCode(全局返回码)中定义一段错误码,通过输出结果返回。
4. 使用Map作接口方法的输入、输出,还美其名曰:简单灵活。有时候甚至只有一个Map作输入。
—— Map非常不适合作公共API方法的输入输出(仅非常特殊时除外),直接导致弱类型问题、易引发潜在BUG且调试困难、不容易书写数据对象的(反射式)校验代码。另外,有些人反映 hessian协议下存在Map中的自定义对象的序列化问题,其实很简单:1、不要使用Map;2、覆盖一下这些对象的hashCode方法
好的接口方法的输入、输出无不定义为强类型,且应分别输入多个不同的业务数据对象(易于校验、维护与测试)。
5. 接口包不提供输入对象的校验,对象长度、格式等只在文档中说明
—— 建议接口包统一提供输入对象的校验:是否必填、长度与格式。最好 定义一个Validatable接口:含validate方法,同时让所有输入对象实现之
6.远程数据对象未实现序列化接口。
7. 未考虑远程接口的安全性问题
——有两种方案可让远程接口提升安全性:一、使用HTTPS协议;二、 接口方法上增加一个安全码参数作安全检查(方法一:调用方与被调方用同一密钥对时间戳作DES加解密以便比对)。前者属于协议层安全,后者属于应用层安全,两者也可以同时提供,我建议仅用后者即可。
8.不作单元测试。
—— 关键类的public方法最好先作单元测试。另外,如完成一个接口方法的实现类,最好书写单元测试代码自测之(事半功倍之举)
还有很多细节问题,需要你自己的分析、判断与经验。这里请牢记一句话: 细节决定成败!当你完成一个 接口类库包,就可以打上版本发布(建议与接口文档同时发布,且版本保持一致)。 如以后升级类库,记住先升级文档
七、【后记】
到此,我已经比较全面的介绍了接口设计主要原则与重点,但仅靠别人的分享与培训是不足以成为一位出色的设计师的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值