zoukankan      html  css  js  c++  java
  • 契约

    魔兽争霸3中死亡骑士(Death Knight)出生时就会说一句:

      The pact is sealed.

      契约已签订。

    看过N多童话故事和电影的小伙伴们肯定熟悉这种场景:

      大反派斗不过主角,处于劣势时,就会与诸如恶魔签订契约,以自己的青春换取强大的力量,即:

        青春 --> 恶魔     恶魔  --> 力量  

    我们把这个再改变一下:

      恶魔 【得到】{青春}  ->  {力量}

      看起来有点眼熟,这不就是function/method干的事情吗?

      

      function 与恶魔签订契约(青春) {
        return 力量;
      }

        

    拿一个PHP简单的函数来说吧,此函数是这样的:

    function getFullName($givenName, $surname) {
        return $givenName.' '.$surname;
    }

        对于调用方来说,如此调用:$fullName = getFullName($realGivenName, $realSurname);

      输入 $realGivenName 和 $realSurname 不知道是否返回结果,有结果也不知道是什么。

      这里 $givenName和 $surname 两个形参对比之下就是契约条件,而返回的值就是契约回馈。

          

    每天在敲代码,原来就是在写各种各样的契约,然后各个契约被各种各样的大反派(调用方)签订(调用)。

    再来看Java的一个方法

    public static String getFullName(String givenName, String surname) {
        return givenName + " " + surname;
    }

     给一个String类型 和 一个String参数,返回一个String 类型的结果;

       

    去跟PHP对比一下,发现Java的Method契约条件的限制更加严格了,而契约回馈的描述也更加准确了。

    即PHP函数在调用时,函数形参如果不限制类型的话,可以是任意类型($givenName 可以是一个int,也可以是array,甚至是一个resource类型,或者干脆是null),

    基于动态语言的特点,甚至还可以传多于/少于(少于的话PHP会报Warning级别的错误)function规定的参数数目进去!

    所以在上面这种实现在遇到特殊情况下,就会出现意想不到的结果,因此具体实现要对变量类型、值做各种判断;

    而Java在实现内则不需要做类型判断,只需要处理空的情况即可;

    对于return 的结果来说,PHP function实现可以返回 null、int,array,resource... 又是不限制类型和值!契约回馈又是模糊的描述……

    所以,PHP function/method 契约是模糊的,契约回馈的描述也是模糊,而Java则更加强调契约发起方和契约执行方的明确的责任;

    如此这般,PHP 一个function/method 实现(契约执行方)就头大了,调用方(契约发起方)传过来的参数(契约条件)很有可能存在

    意想不到的情况,于是就需要在实现内加类型判断, 处理空或者其他情况。调用方也不知道实现是否真的能达成契约描述(function/method名称,注释等)

    那样的美好的结果,调用方又得对实现返回进行判断。

    而Java则只是对象参数需要处理null的情况,因为有一步编译的过程,类型则不需要费心。即在通过编译后,契约双方的基本条件和回馈描述被保证了。

    PS:这么一说,编译器(Compiler)听起来就像是一个公证人似的。

    总的来说,PHP因为不必在声明变量或者制定方法签名时声明类型,所以是弱契约。    

     

    弱契约的好处是显而易见的:

      调用方的责任限制变少,执行方(实现)的责任 加重(即兼容 各种参数情况),那么只需要一个契约执行方,就可以满足多种调用方的情况。

      即一个function/method实现,调用方多种情况来调用都是没问题的;

      我们也可以把这种实现成为健壮的实现;

    Java则是强契约,好处不必多说,但是劣势对比弱契约也是很明显,调用方参数若是出现了另外一种类型或者参数变多/变少,则不得不重载(Overload),

    如果业务复杂起来,重载方法写起来简直是恶心;

    说道这里泛型横空出世,我们可以理解泛型其实就是在强契约和弱契约之间的一种折中,即Method契约不再死板地限制某个具体类型,也不死板地规定

    返回某个具体类型,而是规定为某一系列的类型,即在强契约的上弱化了一些,将类型限制放宽。

    使用了泛型的方法,则可以满足调用方的某一系列的参数类型情况,让我们少些重载方法,减少了代码量 :)

    return ;

  • 相关阅读:
    数据结构笔记
    简单数学
    分析代码练习--长期目标
    C#基础--面向对象计算器
    经常喜欢看的网站
    C#基础--面向过程计算器
    C#中的五个访问修饰符
    SQLServer 游标详解
    快速产生大量顺序数字序列
    VSCode 必装的 10 个高效开发插件
  • 原文地址:https://www.cnblogs.com/Joynic/p/6828590.html
Copyright © 2011-2022 走看看