• HIT软件构造课程3.2总结(Designing Specificaton)


    本节转向“方法/函数/操作”如何定义

    上一节是名词 这一节是动词

    1.编程语言中的函数和方法

      方法

      使用者不需要知道方法内部如何实现,这叫做“抽象”。

      参数

      参数类型是否匹配,在静态检查时完成。

      返回值

    2.规约:程序用于沟通

    (1)程序中的文档

      java API

    • 类的层次,类接口的实现列表
    • 直接的子类,对于一个接口的实现类
    • 类的描述
    • 构造方法
    • 能调用的所有方法
    • 对于每个构造器和方法的详细说明,方法签名:返回类型,方法名,参数,例外情况。

      设计文档

      程序的沟通

      代码中蕴含的设计决策:给编译器读

      注释形式的涉及决策:给自己和别人读

    (2)规约和契约(方法的)

      规约(契约)


      client:客户端,implementer:实现者

      双方都要遵守

      为什么做规约

      客户端只需理解spec即可

      规约可以隔离变化,无需通知客户端。规约可以提高代码效率(输入正确性由调用者保证)

      扮演“防火墙”角色:调用者不需知道具体实现,实现者不需知道具体输入实现(解耦)

      只说能做什么,不说具体实现

    (3)行为等价性

      站在客户端角度看行为等价性。

      根据规约判断行为是否等价

    (4)规约结构:前置条件和后置条件

       
      规约结构

      前置条件是需求,后置条件是效果。

      前置条件约束客户端,后置条件约束开发者。

      前置条件满足则后置条件必须满足。

      Java中的规约

      静态类型声明也是一种规约,据此可以进行静态类型检查。

      方法前的注释也是一种规约,但是需要人工判定是否满足。

      前置条件:@param 后置条件:@return @throws:避免重复,可以不写类型

      规约可能讨论什么

      可以讨论参数和返回值,例外情况,但是不能局部变量和私人领域。

      可变方法的规约

      可变方法会改变参数值。

      除非在后置条件里面说明过,否则方法内部不应该改变输入参数。尽量少使用可变的对象。

      可变对象让契约变得复杂

      程序中可能有很多变量指向同一个可变对象,无法强迫类的实现和客户端不保存可变变量的别名。

      可变对象减少了可变性

      使用不可变的对象,在规约里面限定住。

    (5)测试规约

      黑盒测试

      不知道内部实现。我不知道谁是错的,但是我知道怎么错。

      (接口的规约override,不用再写一遍)

    3.设计规约

    (1)规约的分类

      比较规约

      判断哪个规约更好:规约的正确性、规约的强度、规约的陈述性。

      规约的强度

      规约强度大小:前置条件越弱规约越强,后置条件越强规约越强。

      可以用强规约替代弱规约。

      越强的规约,意味着开发者的自由度和责任越重,而调用者的责任越轻。

      规约的确定性

      给定一个的输入,输出是唯一的、明确的。  

      操作式和声明式规约

      操作式规约:伪代码,声明式规约:只有初终状态。

      声明式规约更有价值,内部实现的细节不在规约里呈现。放在代码内部注释里呈现。

      声明式规约

    (2)规约图解

      某个具体实现,若满足规约,落在其范围内。

      更强的规约,表达为更小的区域。

    (3)设计一个好规约

      规约的质量

    •     规约应该是内聚的:规约做了两件事就要分开成为两个方法。
    •     规约应该是信息丰富的:不能产生歧义。
    •     规约应该足够强:开发者应该尽可能考虑各种特殊情况
    •     规约也应该适当弱:太强了开发者实现不了。
    •     规约应该使用抽象类型:List or Set
    •     前置条件或后置条件:不写前置条件,就要在代码内部检查。开发者可以在规约里加入前置条件,把责任推给客户端。惯用的做法是:不限定太强的前置条件,而是在后置条件中抛出异常:输                 入不合法

     

  • 相关阅读:
    Linux DNS配置
    SqlCommandBuilder 为SqlDataAdapter 提供 update、insert、delete 命令(自己利用select命令自动从数据库元数据推断)
    Dev中GridView——事件
    select 动态赋值 layui重新渲染
    url-loader和file-loader的区别和使用
    Fetch API
    Fetch API
    FormData上传文件
    Buffer、ArrayBuffer互转
    if exists用法(判断对象的用法)
  • 原文地址:https://www.cnblogs.com/upuphe/p/12638837.html
Copyright © 2020-2023  润新知