前言

如果你或你带领的团队经常会写出一些BUG,日常不是在解决BUG就是在解决BUG的路上,那么你的项目一定是应验了墨菲定律,并且在开发时并没有足够考虑防呆设计。团队越是疲于奔命,错的越是多。

简记

任何可能出错的事情都必将出错,因此应当尽可能降低错误出现的概率。

到底什么是墨菲定律,又该如何防呆

首先尽管实际上BUG不会100%发生,我们却依然需要假定所有一切可能发生的BUG都会发生,在我们认知范围以内尽可能的去避免产生BUG,这样的做法是软件工程保证健壮性的基本诉求。特别是设计和开发各种模块、UI、接口甚至整个系统。

然而我们要知道的是,完全杜绝BUG存在是不可能的。无论是微软还是苹果这样的公司,每个月、每年都会发布一些系统补丁,就是用来修复已经发现的BUG或漏洞。很多公司花费在修复问题上的人力资源成本早就超过了当初设计系统的投入,所以这也是为什么很多高级程序员触碰到其他高级程序员所写的代码时总是想重构,因为两个人对于BUG的预见性和认知范围是有差别的,结果会发现该掉进去的坑还是会掉。因此才会出现“造轮子一时爽,修轮子时时爽”、“一次交付,终生维护”的现象,重构系统的人便会成为下一个接盘侠,解放了上一个造轮子的人。

大多数情况下问题是可以被扼杀在摇篮中的。例如,如果出现某个语法错误,编译器会因语法错误抛出异常,告诉你这个代码不能正常编译,这就是一种防呆措施。

图1、登录时对用户输入进行校验可以有效避免SQL注入攻击

在进行UI开发(或称为前端开发)的情况下,你可以判断用户输入的内容是否合规,这样可以避免错误的数据进入到系统里,比如电商系统的价格标为0或负数是不可以的、销售价低于进货价是不允许的。

在多线程或具备异步调用的环境中,你可以在纸上先规划好代码要执行的时序,把时序调整好,并考虑好一切同步和回调措施,比如打卡类应用,不应先入为主的认为3秒内软件一定能拿到GPS定位,然后第5秒开始展现允许打卡界面,万一第6秒才能拿到经纬度呢?所以一定要在拿到GPS定位之后再做回调。那如果一直拿不到呢,也要考虑是否让用户重新获取一下GPS定位或进入设置界面开启权限,而不是出现问题之后让用户看着空白页面发呆。

图2、一个典型打卡异步获取GPS定位的场景

图3、上述案例的典型糟糕设计,需要让用户等7秒,而且容易出现空白页现象

以上只是举了两个小例子,以这种方式设计系统并不能保证BUG一定不存在,但你如果不去认真设计并竭力避免、用心思考,那么BUG一定会比你想象的速度来的更快。系统是人创造和使用的,人应该努力实现“万无一失”的设计。

根据墨菲定律,软件可能会以各种稀奇古怪的方式发生匪夷所思的错误:复制数据可能不同步、常量可能被破坏、先决条件可能被违反、接口可能被乱用、输入参数可能顺序与函数定义的不一致、可能会出现拼写错误、值可能会混淆等。而这种情况下大多数BUG是不可复现的,这也是最为致命的一点,要想尽可能避免这些糟糕的设计,唯一的办法就是多做实战项目、多敲代码、多设计、多思考,用大量的失败经验来覆盖应用场景。

再好的程序员、工程师、架构师也都会出错。所以最好先实现一个高度内聚、足够简单的业务模块,围绕着它再增加功能,因为这样会减少出BUG的可能性,而且这种层层包裹式和模块协作式的设计有利于维护代码:如果一定要修复某个BUG,现有的功能将被就改或增加新的特性(增加新特性意味着可能需要更多的入参),未来可能会触及每一段代码。因此,在进行维护工作时引入故障的可能性越小,设计越好。

反面教材

1、参数容易写反的反人类设计

例如你的API是这么设计的

// 创建一个新订单(订单号,指定UUID[可选])
createNewOrder(String orderCode,String uuid)
// 获取订单明细(指定UUID,订单号[可选])
getOrderDetail(String uuid,String orderCode)

首先,createNewOrder的订单号和uuid如果后续能通过set方法加上,尽量不要在上面加参数,除非这是一个高频调用的函数,可以视作语法糖。

其次,我们可以写两个getOrderDetail方法分别加上ByUuid和ByCode,使之语义明确。

那么原来这么设计的API很有可能其他程序员调用的时候就把参数写反了,而且编译器还会认为这样是合法的。

2、过分依赖Object,没有用到泛型

一个系统里到处充斥着没有泛型或者泛型都是Object的List和Map时,这个系统将很难进行维护。例如下面这样的:

Map result=new LinkedHashMap();
result.put("status","success");
result.put("data",object);
result.put("message",null);

设想一下,这样的代码在后台重复几百次,到处都是魔数,只要success少了一个s,或者data对应的数据从对象换成了数组,前端应当如何接?假设前端为了快速完成工作任务,委屈接受了错误的拼写,那未来换回正确拼写的概率又有多大,是不是被钉在公司的耻辱柱上了?这个技术债是否就伴随这项目一生了?

所以我们可以用一个对象来表示result,固定了status、data和message的格式以及可能出现的响应情况,封装诸如RestResponse.success(List<BaseEntity> list)、RestResponse.error(String message)的静态方法是不是会更可靠一些呢。

总结

要知道墨菲定律所要解决的一般来说都是低级错误,所以我在这里也称之为“防呆设计”。积累防呆设计要点的过程是需要大量项目洗礼(折磨)才能把风险时时刻刻刻在心上的。因为积累这种经验需要大量的阅历、精力和时间,所以软件从业人员应当在处理完或见证完一个BUG解决后特意去记一下、并发散思考一下这种低级错误会不会在别的场景也会出现,并时长温习,才能从根本上提高软件设计水平。

高级程序员必会的程序设计原则 —— 墨菲定律及防呆设计相关推荐

  1. 高级程序员必会的程序设计原则 —— 复杂度守恒原则

    前言 软件设计上我们寄希望于能够让软件更简单.更容易维护,但是一面是害怕墨菲定律的应验,一方面又害怕遵循纯粹原则导致出现更多的缺陷.我们可以认为简单和复杂分别是跷跷板的两端,而它的支点就是复杂度守恒原 ...

  2. 程序员必懂的程序设计原则

    来自:source: //bigjun2017.github.io/2018/11/24/ruan-jian-she-ji/ruan-jian-cheng-xu-she-ji-yuan-ze 一.前言 ...

  3. SqlServer注意事项总结,高级程序员必背。

    本篇文章主要介绍SqlServer使用时的注意事项. 想成为一个高级程序员,数据库的使用是必须要会的.而数据库的使用纯熟程度,也侧面反映了一个开发的水平. 下面介绍SqlServer在使用和设计的过程 ...

  4. 成为高级程序员必学知识点!

    技术选型 网关:Nginx.Kong.Zuul 缓存:Redis.MemCached.OsCache.EhCache 搜索:ElasticSearch.Solr 熔断:Hystrix.resilien ...

  5. 程序设计考试大纲(高级程序员级)

    一.考试说明 1.考试要求: (1)熟练掌握面向对象编程技术,用C/C++语言熟练编制程序: (2)了解CASL汇编语言的程序编制: (3)掌握软件设计的方法和技术: (4)掌握数据结构.程序语言.操 ...

  6. 程序员必读书单1.0

    原文:http://lucida.me/blog/developer-reading-list/ 本文把程序员所需掌握的关键知识总结为三大类19个关键概念,然后给出了掌握每个关键概念所需的入门书籍,必 ...

  7. 程序员必看的书籍推荐

    程序员必看的书籍推荐: 推荐1:Python 网络数据采集 作者:Ryan Mitchell 译者:陶俊杰,陈小莉 原书4.6星好评,一本书搞定数据采集 涵盖数据抓取.数据挖掘和数据分析 提供详细代码 ...

  8. 【转】程序员必读书单

    作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://lucida.me/blog/developer-reading-list/ 关于 本文把程序员所需掌握 ...

  9. java书籍_Java程序员必看的 13 本 Java 书籍!

    原文:Java程序员必看的 13 本 Java 书籍! 作者: java技术栈 关乎于程序员,除了做项目来提高自身的技术,还有一种提升自己的专业技能就是:多!看!书! 毕竟,书是学习的海洋呢!So,J ...

最新文章

  1. Linux动态库(.so)搜索路径
  2. 实战Gradle——第1章 项目自动化介绍
  3. 【51CTO学院三周年】写给自己的51cto
  4. boost::flyweight模块实现自定义工厂模式的示例
  5. 【C++grammar】文件系统以及path类使用
  6. java延迟队列,java高级面试笔试题
  7. Flutter进阶—网络和HTTP
  8. 灵机一动之优雅实现用例顺序插入
  9. Android 微信分享后留在微信,没有回调的问题解决方案
  10. C++ string转char* string转char[]
  11. 使用组策略配置QoS
  12. android 控件获取 获取焦点
  13. android studio计算机代码,Android Studio实现简易计算器
  14. wpf OpenClipBoard CLIPBRD_E_CANT_OPEN
  15. 用人机对话系统设计逻辑探究人工智能产品经理
  16. windows中mysql服务无法启动
  17. 软件测试笔记(十六)- 缺陷轰炸和beta测试
  18. 制作简单的个人网站,将本地网站公布在网络上
  19. mac iCloud 关闭后 桌面文件不见了
  20. 武汉公交车司机的技术真NB

热门文章

  1. 也说说ADC以及ADC的主要技术参数及分类介绍
  2. 电脑屏幕由刺眼的白色改为淡绿色
  3. 布兰迪斯大学计算机美国大学排名,布兰迪斯大学排名多少 美国和世界排名介绍...
  4. 同样是后端程序员,你掌握如何用Grafana做出漂亮的可视化界面了吗?
  5. Flash Helper Service 这个流氓,动不动弹出广告!!
  6. 有些人 总是莫名其妙的得罪了
  7. 加拿大Introspect I3C 协议分析仪(Analyzer)及训练器(Exerciser)
  8. 揭秘李佳琪直播带货绝招,学会它让你直播带货效益翻倍。
  9. 入门级前端选手半路接手vue项目实录
  10. 万物互联时代,Check Point开启网络安全新未来