防御式编程是一种主动预防问题的编码风格,作为一种编程实践,防御式编程是由很多小目标融合而成的,例如编写具有可读性的代码、正确的命名规则、检查所有函数的返回值、以及运用设计模式。在防御式编程里,细节决定了一切。自底向上的方法让整个应用程序更加健壮、更加正确、以及更具有更佳的可扩展性。说白了,防御式编程基本上就是由各种常识性的实践所组成的。比如下面的这个表达式:
price=price*1.05;
这条语句有一个很明显的问题.它的可读性很差,是糟糕的编程实践和常识性问题的典型例子.它的问题就是数字1.05。这个数字的上下文是什么?1.05可以表示价格数量、税率、服务费用、甚至可以是版税。这个数字的上下文是非常重要的。如果不理解这一点的话,维护程序员就有可能不适当地修改这个公式或是错误地使用其结果。类似上面公式里的这类数字是很难优化的。这是第二个问题。而下面的代码就是一个防御编程的绝佳范例。它不但修正了前面提到的两点问题,同时还是一段很好的自然描述代码。
price=price*priceIncrease;
程序自己是不会出错的。一个正确的程序到了明天、下个礼拜、乃至几年以后仍然是正确的。而无论何时何地,引入代码问题的只有程序员。正确的代码需要程序员遵守严格的纪律。防御式编程正是这样的一组编码标准,为创建正确的代码提供了稳定一致的程序员纪律。在很多的到时候,防御式编程可以预防那些由于疏忽造成的问题。比如如下代码:
if(a>5)
a+=5;
上面的 if 语句为真时要执行的语句是(a+=5;)。防御式编程要求这句应该放在一个代码块里。这不但是强制的,而且也是非常重要的。如果不这么做的话,程序员可能会给它加上第二条语句却忘了代码块。这样的代码还是可以通过编译的。但是你就在应用程序里引入了一个很难发现的bug。严格的测试有可能(但是不一定)发现这个问题。这个例子展示了细节对于防御式编程的重要性。下面是修正后的代码:
if(a>5){
a+=5;
}
防御式编程需要有合理理由的最后期限。你必须有时间去思考如何编程。把编程完全当做是一项技术过程的想法绝对是一种谬误。优秀的程序员很有创造性的,他们需要时间来进行分析和创新。太短的期限只会压迫思考的时间和降低创造力。你应该考虑在项目计划里加入一个叫做“思考”的任务。要是怕老板会皱眉头的话,可以给它其一个华丽的名字,比如通过坚实的应用程序探索未来的受益,或者写上在员工休息室里打游戏机也行。
防御式编程会增加应用程序的代码量。但是产品开发的目的是什么:更少的代码还是正确的代码--特别是当性能区别不是那么大的时候?无论如何,可以证明的是,客户更喜欢正确的代码,而不是一个好像快了那么一点点的应用程序。“在所有情况下都要假设会发生最坏的事情”是防御式编程里非常重要的信条之一。最糟糕的问题就是程序员假设它们不会发生。代码应该考虑到所有的问题。例如,在switch语句里一定要有 default case,就算它发生的可能性微乎其微。最坏的也就是default case 里的错误处理代码永远不会被执行。而最好的情况时,你正确处理了将来可能会发生的问题。
防御式编程和C#
C#的设计里随处可见防御式编程的影子。C++就像是西部荒野一样,基本上可以让你为所欲为。程序员在C++里有很大的灵活性,这是一把双刃剑。程序员手上有太多的控制权,有些人根本驾驭不了。C#正是试图想要控制C++里这种太过自由的局面。这样,程序员就能更加专注在解决商业问题上,而不用在语言细节上纠缠不清。赋值问题就是最佳例证。在C++里,下面的代码是合法的:
int a=5;
if(a)
{
//Do whatever
}
在C++里, true 是非零值,零代表 false。这表示整数值可以代替布尔可以出现在上面这样的表达式里。虽然用整数值代表布尔值可以说是相当的灵活,但是使用不当的话也很容易产生错误。原因之一是程序员会忘记规则。true和false 的定义在不同的语言之间有所不同,即便是经验丰富的程序员有时候也会混淆。而且,这个代码的可读性也不好。在C#里,布尔表达式限制在布尔值里(true或者false),这样显然更加清晰。清楚的表述可以防止问题的出现。这是在C#强制防御式编程的例子之一。这是另一个例子。下面的代码在C++里是合法的。控制转移语句(比如break语句)在每一个case语句里并不是必须的。因此,下面的代码可以很巧妙地计算出阶乘。C#在每个case语句之间都要求有控制转移语句,所以这样的代码是无法编译的。为什么?因为在switch块里遗漏break语句是一个常见的C++错误。在C#防止这类错误是防御式编程的一种形式。
int factorial=s;
int result=1;
switch(factorial){
case 5: result*=factorial--;
case 4: resault*=factorial--;
case 3: resault*=factorial--;
case 2: resault*=factorial--;
}
相关推荐
防御式编程 Defensive Programming.PPT完整版(精品课件) 大纲: 保护程序免遭非法输入数据的破坏 断言 错误处理技术 异常 隔离程序 辅助调试代码
防御性编程是一种软件开发策略,旨在提前预测并防止潜在错误,从而提高软件的稳定性和可靠性。在本主题“防御性编程之三”中,我们将会深入探讨如何在C++编程中利用源码和工具来实现有效的防御性编程。这篇博客文章...
这些技术覆盖了代码的组织与布局、基本编程习惯以及防御式编程等核心主题。通过深入理解这些知识点,可以帮助开发者编写出更稳定、更易于维护的代码。 #### 核心知识点详解 ##### 一、防御式编程(Defensive ...
- **防御式编程**:重点讲解了防御式编程的概念,包括如何在设计子系统时考虑各种可能的异常情况。 - **安全策略**:探讨了如何通过合理的输入验证和边界检查等手段来防止外部攻击或数据损坏。 4. **第4章 对程序...
【描述】:本章专注于提升MapReduce应用的可靠性,通过MRUnit创建单元测试,进行本地实例测试,理解和调试MapReduce,以及采用防御式编程策略处理可能出现的问题。 【标签】:技术方案 【正文】: 在开发...
实验报告的标题是“哈工大hit软件构造lab4实验报告”,主要涵盖了异常与错误处理、防御式编程以及测试和调试三个核心主题。这是一份针对2020年春季学期计算机学院《软件构造》课程的实验内容,旨在让学生深入理解...
- **第3章:为子系统设防** - 探讨了如何通过防御式编程来提高系统的健壮性和可靠性。 - **第4章:对程序进行逐条跟踪** - 指导读者如何进行详细的代码审查和调试过程。 - **第5章:糖果机界面** - 通过一个具体...
6. 安全编程模式:书中的源码会展示如何使用一些安全编程模式,如防御式编程、最小权限原则和编码规范,以减少安全风险。 7. 输入验证:有效的输入验证是防止攻击的第一道防线。书中可能详细阐述如何对用户输入进行...
实验报告“Lab-4 1160300314 朱明彦 report 1”涵盖了软件构造课程中的重要主题,包括异常与错误处理、防御式编程、测试和调试。以下是这些知识点的详细说明: **异常与错误处理** 异常处理是软件开发中的关键部分...
这种防御式编程方法能够显著提高软件的整体稳定性。 #### 第4章 对程序进行逐条跟踪 这一章节聚焦于程序调试技巧,特别是如何通过逐行分析代码来定位和修复错误。它涵盖了使用调试工具、设置断点和单步执行等技术...
7. 防御式编程不被提倡:在LeetCode题解中,为代码简短而忽略了防御式编程的一些原则,如不检查malloc/new返回指针是否为nullptr,不检查函数入口参数的有效性等。 8. 编程学习:本书假定读者已经学习过《数据结构...
- **流行性**:示例代码应体现当前最佳编程实践,如使用Unicode、错误处理、防御式编程等。 - **可靠性**:代码示例必须符合法律、隐私和政策标准,不得包含侵入性或低质量的编程实践,且所有安装和执行步骤应可逆。...
此外,文档也提到了防御式编程,这是一种在代码编写过程中加入额外检查以防止潜在错误的编程习惯,比如检查指针是否为空,验证函数输入参数的有效性等。然而,文档指出,在LeetCode的解题环境中,为了编写更简洁的...
本书详细阐述了防御式编程的原则和实践方法,包括预条件检查、断言使用等。这些技巧对于提高软件的质量和可靠性至关重要。 #### 三、标准C++库 **3. 深入字符串** 字符串是编程中最常用的数据类型之一。本章重点...
防御式编程是一种预防性的编程策略,旨在尽早发现并处理潜在错误,以避免程序在运行时出错。在未来的工作中,我需要更加注重编写健壮的代码,以防止可能的问题发生。 另外,我在项目架构设计方面还有待提升。在项目...
但是,这一点对于实际的软件开发而言,防御式编程是非常重要的,因为它可以提高代码的健壮性和可维护性。 在如何使用LeetCode的问题上,作者建议根据不同的情况采取不同的策略。对于即将参加面试的人来说,他建议...
防御式编程和契约式编程则是提高代码质量的方法,前者要求对所有输入数据保持警惕并处理异常,后者则规定模块间应遵循统一的通讯协议,违反协议则抛出异常。 【团队合作】 技术团队的成功很大程度上取决于团队合作...
《浅谈C语言中影响程序安全性的几点因素》 C语言作为一门强大的编程语言,其灵活性和高效性深受程序员喜爱,然而,这也...理解并掌握这些知识点,结合防御式编程,可以帮助程序员编写出更安全、更稳定的C语言程序。