首页 > 编程语言 >编程思想

编程思想

时间:2022-08-16 21:23:55浏览次数:54  
标签:错误 思想 健壮性 编程 防御 契约 义务

1. 防御式编程

1.1 墨菲定律

墨菲定律:如果有两种或两种以上的方式去做某件事情,而其中一种选择方式将导致灾难,则必定有人会做出这种选择。

墨菲定律主要内容:

  1. 任何事都没有表面看起来那么简单;   
  2. 所有的事都会比你预计的时间长;  
  3. 会出错的事总会出错;
  4. 如果你担心某种情况发生,那么它就更有可能发生。

1.2 防御式编程概念

防御式编程:子程序应该不因传入错误数据而被破坏,哪怕是由其他子程序产生的错误数据。

防御式编程和防御式驾驶
防御式编程,这一概念来自防御式驾驶。在防御式驾驶中要建立这样一种思维,那就是你永远也不能确定另一位司机将要做什么。这样才能确保在其他人做出危险动作时你也不会受到伤害。你要承担起保护自己的责任,哪怕是其他司机犯的错误。

1.3 防御哪些地方

  1. 边界防御:检查所有的外部输入
    在防御式编程的理念中,所有的外部输入都是不可信的,需要校验是否在可允许的范围内。这里需要检查的项包括,空指针、数组越界、不合法入参等。特别是当我们在写一个公共方法时,不确定这个方法会在未来某个时刻,被某个外部系统调用,做好输入检查既能保护自身程序运行的健壮性,又可以让外部系统放心调用。
  2. 异常处理:在正确性和健壮性之间做好取舍
    正确性:程序永不返回不准确的结果,即使这样做会不返回结果或是直接退出程序。
    健壮性:系统在不正常的输入或不正常的外部环境下仍能正常运行,哪怕输出结果是错误的或者不完整的。
    正确性和健壮性往往是相互矛盾的,当我们检查出错误数据后,还需要决定如何处理它。防御性编程不会掩盖错误,也不会隐藏bug。这需要在健壮性和正确性之间做权衡。
  3. 应检尽检:没有完全可靠的外部环境
    我们在coding时,会有很多外部方法的调用和交互,要对所有的外部调用保持警惕。这些API或者三方类库也是人写的,人写的就意味着可能有bug。一种好的思路是尽可能地按照自身逻辑,对外部调用做检查和异常处理(exception handle)。
  4. 显示约束:简单直接的代码风格
    在防御式编程中,我们提倡使用“最笨”的方式写代码,尽量少的使用一些语法糖或者隐性规约。
  5. 减少依赖:write once, run anywhere
    "write once, run anywhere"是Sun公司用来展示Java程序设计语言的跨平台特性的口号,这本身就是一种防御式编程的理念体现,即在代码中减少对环境的依赖,确保外界环境改变了,程序依然可以正常运行。
  6. 傻瓜式注释
    代码是给系统看的,注释是给人看的。要想代码具有比较好的可阅读性,应该把自己当作傻子去添加注释。(这个和clean code 的理念不同,clean code提倡代码即注释,个人认为这是一种理想化的情境)
  7. 避免过度设计
    避免预防不可能会发生的错误,过多的防御式代码也会导致程序显得臃肿、难以维护,同时程序的性能也会受到影响。

1.4 总结

防御式编程是一种安全的编程思想,本质上是要求开发人员对代码和线上环境报以辩证的态度和敬畏之心。它通过以下途径,从而来提升系统健壮性:

  • 提高工程质量——减少bug和问题;

  • 提高源码可读性—— 源码应该变得可读且可理解,并且能经受code review;

  • 让软件能通过预期的行为来处理不可预期的用户操作。

作为一名优秀的开发者,不能将希望完全寄托于测试,测试驱动开发,而是在设计、开发阶段,对系统的异常和边界有充分的认知和考量,这是防御式编程带给我们的思考。

2. 契约式编程

2.1 合同描述

在人类的社会活动中,契约一般是用于两方,一方(供应者)为另一方(客户)完成一些任务。每一方都期待从契约中获得利益,同时也要接受一些义务。通常,一方视为义务的对另一方来说是权利。契约文档要清楚地写明双方的权利与义务。契约合同能保障双方的利益,对客户来说,合同规定了供应者要做的工作;对供应者来说,合同说明了如果约定的条件不满足,供应者没有义务一定要完成规定的任务。

2.2 契约式编程概念

契约的特点:

  1. 契约关系的双方是平等的,对整个bussiness的顺利进行负有共同责任,没有哪一方可以只享有权利而不承担义务。
  2. 契约关系经常是相互的,权利和义务之间往往是互相捆绑在一起的;
  3. 执行契约的义务在我,而核查契约的权力在对方;
  4. 我的义务保障的是你的利益,而你的义务保障的是我的利益;

2.3 DEMO理解

if (dest == NULL) { ... }

这就是义务,其要点在于,一旦条件不满足,我方(义务方)必须负责以合适手法处理这尴尬局面,或者返回错误值,或者抛出异常。

assert (dest != NULL);
这是检查契约,履行权利。如果条件不满足,那么错误在对方而不在我,我可以立刻“撕毁合同”,罢工了事,无需做任何多余动作。

2.4 总结

我们以往对待“过程”或“函数”的理解是:完成某个计算任务的过程,这一看法只强调了其目标,没有强调其条件。在这种理解下,我们对于exception的理解非常模糊和宽泛:只要是无法完成这个计算过程,均可被视为异常,也不管是我自己的原因,还是其他人的原因(典型的权责不清)。

  • 报告:其他模块未能履行契约,本过程无需作出任何反应,仅需告知对方。
  • 异常:对方完全满足了契约,而我依然未能如约完成任务。

标签:错误,思想,健壮性,编程,防御,契约,义务
From: https://www.cnblogs.com/Andrew-Zhou/p/16593020.html

相关文章

  • JavaSE:第十五章:网络编程
    史上最全的知识体系脑图,覆盖所有知识点,所有细节,注意事项。网络编程:包含网络编程概述,通讯要素,IP和端口号,网络通信协议,InetAddress类,TCP网络通信,UDP网络通信,URL编程。更多......
  • 《安富莱嵌入式周报》第278期:基于RUST编程语言RTOS,固态继电器芯片,微软发布物联网组件
    往期周报汇总地址:http://www.armbbs.cn/forum.php?mod=forumdisplay&fid=12&filter=typeid&typeid=104 本周更新一期视频教程DSP视频教程第10期:DSP运算加速的精髓,含SI......
  • 英语词典,基于文本词典库,TTS发声,RichEdit显示,Win32 SDK编程
    用Win32SDK写的英语小词典,用朗文英英词库,词库是一个TXT文件,显示用RichEdit控件,发音用TTS采用MutiByte编码,没法显示音标,可以即时查找单词,速度0.1s以下,即使顺序查到......
  • Java - 网络编程 ,网络通信三要素,TCP通信,实现 TCP 网络通信程序,使用 TCP 网络通信实现
    第十三章、网络编程13.1、软件架构CS/BSC/S结构:全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、迅雷等软件。B/S结构:全称为Browser/Server结构,是指浏......
  • Vue 组件化编程
    Vue组件化编程  非单文件组件一个文件中包含n个组件。<!DOCTYPEhtml><html><head><metalang="zh-cn"><metacharset="UTF-8"><title></titl......
  • .NET异步编程模式(二)
    在C#1的时候就包含了APM,在APM模型中,异步操作通过IAsyncResult接口实现,包括两个方法BeginOperationName和EndOperationName,分别表示开始和结束异步操作。Demo我......
  • .NET异步编程模式(三)
    EAP(Event-basedAsynchronousPattern)是基于事件的异步模式,在.NETFramework2.0中引入。EAP需要一个有Async后缀方法和一个或多个事件。EAP不再推荐用于新开发。......
  • shell编程之免交互
    Shell编程之免交互一、HereDocument免交互1.HereDocument概述HereDocument使用I/O重定向的方式将命令列表提供给交互式程序或命令,比如ftp、cat或read命令。HereDo......
  • 服务端高性能网络IO编程模型简析
    服务端高性能网络IO编程模型简析一、客户端与服务器端多数网络应用可以分为客户端(client)和服务器端(server)模型,然后中间通过各种定义的协议来进行两端的通信。比如......
  • Spring核心思想Ioc和Aop (面试)
    Spring核心思想Ioc和Aop(面试)注意:Ioc和Aop并不是Spring提出的,在Spring之前就已经存在,Spring只是在技术层面给这两个思想做了非常好的实现。1Ioc1.1下面谈谈你是......