• 不一致性会带来低效率


         协作开发时,接口的不一致性会导致效率低下。一致性大一点来讲,就是一些共同约定的东西,成文的或者不成文的。比如Asp.Net MVC,所有的控制器都被命名被*Controller,如果你不这样命名,Asp.Net MVC很可能不能为你自动创建*Controller实例,无法使控制器按你的意图工作。小一点来说,比如Client与Web Service的协同,如果Web Service的返回具有不一致性,则会造成更多的特殊化代码。当下,与其他组的协作,就遇到这问题。

         首先,这Web Service的实现就不是标准化的。一般来说,Web Service有RESTFul、SOAP两种方式,他们都有自己的标准工作模型,这在维基百科或者一般的书籍里都会看到。很不辛,我们遇到的Web Service就是基于非标准的SOAP建立的。对方在设计这些服务时,显然考虑到了安全性,在SOAP头部中增加了用户名密码验证。SOAP Body中加入了一些自定义的标签,文档里没有明确说明,可能是内部做了一些转换。对于这样的非标准的、或者非惯例的设计方式,Visual Stdio的Service Reference已经罢工,无法自动添加SOAP服务引用。那么我们只能自己构造SOAP请求,利用HTTP协议将方法发送出去。

         在构造HTTP请求与SOAP请求体时,再次遇到了问题——文档的缺乏。只能依赖对方的示例以及直接的沟通。虽然最终确定了SOAP格式,但依然有几个问题没有弄清楚。

    • 对方至今也没有说清楚SOAP头中用户名、密码的编码/加密格式。在构造SOAP头时,我也只是简单的复制了起编码/加密后的信息。
    • SOAP体的完整说明。好在他们的定义具有一致性,只需要改变一些XML node 名,可以很平滑地请求到其他方法。

         可是当我自己构造HTTP HEAD & BODY (SOAP HEAD & SOAP BODY)时,我感觉自己使用的是RESTFul风格的Service,并没有感受到类似WCF那种透明的SOAP/RPC体验。在构造HTTP Request时,我需要指定Request URL,方法名、方法参数,我需要为每个请求构造这些,体验真的很差。虽然尽量提取了一些公共部分用来构造请求内容,但仍然觉得自己做了很多无用功。

         再说说返回结果的不一致性。但就添加记录一项来说,RESTFul会直接返回状态码来标记添加结果。比如201 Created,406 Not Accepted等。SOAP就更好用了,直接返回bool,甚至可以抛出异常。很可惜,我一向好处都没有享受到,还需要写一些额外的代码来解析响应结果。响应结果天然应该是具有一致性的,无非True OR False,再加上一个Error Message。再次很不幸,得益于队友设计能力的薄弱,返回结果变得没有了一致性。可以说,这些Web Service暴露的都不是服务,甚至将数据库表的暴露给了我...我需要知道这些干嘛呢,非要我去理解他们的系统。

    <!-- 比较一致的返回内容 -->
    <Result>
        <Status>true</Status>
        <Message>Created</Message>
    </Result>

          从惯例来说,添加记录是不应该返回什么额外信息的。可惜Service一端需要Client一端的辅助来维护两张表的外键关系,他们需要在某一次Created之后,返回一个唯一的Key。此Key由此次插入时,Service产生,用于下一次作为主键写入到另外一张表。是吧,这么稀烂的设计都能弄出来。说着我都觉得累,明明不关我的事,却还让我去操心这个Key。这很明显是设计的失败,Client的职责是提供自己所有的内容,而不应该去维护服务端的东西——至少是尽最大努力的。从具体内容来看,很明显没有。涉及到工作隐私,不便明说。

          即使真的需要有返回值,那也是可以接受的。只可惜,再一次打破了我的认知.... 在结果解析时,需要更加特殊化的去考虑。当前的返回在上面的XML上添加了一个Node,用来作为返回信息。

    <!-- 有额外参数返回时 --> 
    <Result>
        <Status>true</Status>
        <StudentId>111</StudentId>
        <Message>Created</Message>
    </Result>

         从XML的角度来说,这并没有什么问题。但作为解析来说,这就太特殊化了。我是这样解析的:

    var xdoc = new XmlDocument();
                xdoc.LoadXml(@""); //Response BODY (XML format.)
    var node = xdoc.SelectSingleNode("Result");
               
    var result = new
                {
                    Status= Convert.ToBoolean(
                               node.SelectSingleNode("Status").InnerText),
                    StudentId= node.SelectSingleNode("StudentId").InnerText,
                    Message = node.SelectSingleNode("Message").InnerText
                };
    return result;

         很明显,在 StudentId= node.SelectSingleNode("StudentId").InnerText中参数NodeName是特殊化的,无法将此代码作为一个通用的结果解析函数。结果解析函数关注了具体内容,这不是它的职责。有多少个特殊的返回ID,就需要写入多少个特殊函数。在这种功能性的上下文中,我认为更好的解决方法是将值的具体意义忘记掉。值只对使用者才有意义,他们知道怎么使用,而中间过程不需要。

    <!-- 改进的有额外参数返回时 --> 
    <Result>
        <Status>true</Status>
        <Tag>111</Tag>
        <Message>Created</Message>
    </Result>

         将返回结果的额外信息抽象为Tag之后,就可以用统一的结果解析函数了 :) 

    var result = new
                {
                    Status= Convert.ToBoolean(
                               node.SelectSingleNode("Status").InnerText),
                    Tag= node.SelectSingleNode("Tag").InnerText,
                    Message = node.SelectSingleNode("Message").InnerText
                };
    return result;

          没有额外信息则不用关心Tag字段,需要关注的则可以从Tag获取到想要值——相关者一定会知道Tag内容所代表的具体含义。一点点改变,就能带来工作效率的提升。

  • 相关阅读:
    js获取当前页面url网址等信息
    jQuery 复选框全选/取消全选/反选
    js获取日期实例之昨天今天和明天、后天
    mysql不重启修改参数变量
    php 读取功能分割大文件实例详解
    php批量删除数据库下指定前缀的表
    PHP遍历目录返回统计目录大小实例
    PHP二维数组如何根据某个字段排序
    PHP 如何获取二维数组中某个key的集合(高性能查找)
    jQuery 隐藏与显示 input 默认值
  • 原文地址:https://www.cnblogs.com/jjseen/p/5512414.html
Copyright © 2020-2023  润新知