防卫式编程具体实现——卫语句

HYF Lv3

今天我们来分享无用的有趣的冷知识,叫卫语句

在了解卫语句之前,我们需要先来了解一下什么是防卫式编程

什么是防卫式编程

防卫式编程?嘶~ 你要唠这个我可就不困了噢

我有一个朋友可谓是此道魁首啊,什么变量命名ABCD、什么各种if-else泰山嵌套、真代码假注释那都是手到擒来,代码复杂得连本人都看不懂,妥妥的不可替代性,你就说防没防吧!(是我一个朋友噢,不是我,真的不是我!)

jvav
java

咳咳,开个玩笑,此防御式编程非彼防卫式编程。
防卫式编程(Defensive Programming)是一种编程思想。其核心理念是通过在代码的早期阶段检测和处理潜在的问题,从而防止错误的传播,确保系统的健壮性和可靠性。这种编程思想尤其适用于开发需要高可靠性、高可维护性的软件系统。

防卫式编程的核心理念

预防错误:提前检测并处理潜在的问题,防止错误发生。

简化逻辑:通过卫语句和提前返回等技术,使代码逻辑更加清晰、简洁,减少嵌套和复杂度。

提高健壮性:确保软件在各种边界条件和异常情况下都能稳定运行,不会崩溃或产生未定义行为。

增强可维护性:代码中明确的防御措施和错误处理逻辑,使得维护和调试更加容易。

具体技术和实现方法

输入验证:在处理输入数据之前,确保数据的有效性和完整性。

卫语句(Guard Statement):使用条件检查提前处理异常情况,避免继续执行后续代码。

边界检查:在处理数组或集合等数据结构时,进行边界检查,防止越界访问。

使用断言:在开发和测试阶段使用断言,确保程序在运行时满足预期条件。

异常处理:捕获并处理异常,防止异常传播导致程序崩溃。

保护性复制:在方法接收或返回可变对象时,使用保护性复制以防止外部修改对象的内部状态。

空指针检查:在使用对象之前检查是否为 null,避免空指针异常。

使用不可变对象:通过使用不可变对象,防止对象状态在创建后发生变化。

而我们本次将要了解的是防卫式编程思想中的一种具体实现:卫语句

什么是卫语句

卫语句(Guard Statement)一般用于在代码中尽早地检测和处理特定条件,从而防止程序继续执行可能导致错误或异常的代码块。它通常采用条件语句来实现,以提前退出函数或方法,避免执行后续的代码逻辑。
具体来说,卫语句通常包含以下特点:

条件检查:在执行主要逻辑之前,先检查特定条件是否满足。

提前返回:如果条件不满足,立即返回或抛出异常,避免继续执行后续代码。

简化逻辑:通过提前处理异常情况,减少嵌套层级,使代码逻辑更加清晰和易于理解。

以卫语句取代嵌套条件表达式的精髓就是:给某一条分支以特别的重视。如果使用if-then-else结构,你对if分支和else分支的重视是同等的。这样的代码结构传递给阅读者的消息就是:各个分支有同样的重要性。而卫语句是在告诉读者:“这种情况不是本函数的核心逻辑所关心的,如果它真发生了,请做一些必要的整理工作,然后退出。”

文字描述看不懂?没关系 我也懒得看,首先我们来看一个简单的对比:

1
2
3
4
5
6
7
8
9
10
11
if (true){
if (true){
if (true){
for (){
if (true){
业务代码
}
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if (false){

}
if (false){

}
if (false){

}
for (){
if (false){
continue;
}
业务代码
}

我们可以看到在非卫语句的嵌套条件里,这样的代码很难弄明白每个条件的作用和执行的流程,当你读到最里面一层的时候,估计你已经记不起来当初是为什么走进这个if的了,对代码的执行流程完全不可控了。因为执行你预期的流程并不明显,为了简化这种情况,需要将特殊情况隔离到立即结束执行的单独条件中。

而在我们的卫语句中,只要有一个条件不通过,就快速返回失败,如果到了最后一行,说明所有判断都通过,剩下的就是你预期的结果。而不是一直判断成功进入下一层。

看到这里很多小伙伴可能还是一知半解,接下来我们以案例来具体解释:
假设我们有一个购物车系统,其中包含了多个商品,每个商品都有价格和数量。我们需要编写一个方法来计算购物车的总价,但是在计算之前,需要检查以下情况:

  • 购物车是否为空。
  • 是否支持折扣活动。
    • 所有商品都支持
    • 部分商品支持
    • 全部商品都不支持
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public double calculateTotal() {
double total = 0.0;

// 条件检查:购物车是否为空
if (items.isEmpty()) {
total = 0.0;
} else {
// 条件检查:是否所有商品都支持折扣活动
if (hasAllDiscount(items)) {
total = calculateTotalWithAllDiscount(items);
} else if(hasAnyDiscount(items)){
// 条件检查:是否部分商品都支持折扣活动
total = calculateTotalWithAnyDiscount(items);
} else {
// 全部商品都不支持折扣活动
for (Item item : items) {
total += item.getPrice() * item.getQuantity();
}
}
}

return total;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public double calculateTotal() {

// 条件检查:购物车是否为空
if (items.isEmpty()) {
return 0.0;
}
if (hasAllDiscount(items)) {
return calculateTotalWithAllDiscount(items);
}
// 条件检查:是否所有商品都支持折扣活动
if (hasAllDiscount(items)) {
return calculateTotalWithAllDiscount(items);
}
// 条件检查:是否部分商品都支持折扣活动
if (hasAnyDiscount(items)) {
return calculateTotalWithAnyDiscount(items);
}
Double total = 0d;
// 全部商品都不支持折扣活动
for (Item item : items) {
total += item.getPrice() * item.getQuantity();
}
return total;
}

我们常常将条件表达式反转,从而实现以卫语句取代嵌套条件表达式。例如这个案例:

假设我们有一个银行账户类 BankAccount,其中包含了账户余额 balance、利率 interestRate 和存款期限 duration。我们需要编写一个方法来计算调整后的账户余额,但是只有当账户余额大于 0 且利率和存款期限都大于 0 时才进行调整。

1
2
3
4
5
6
7
8
9
10
11
12
13
public double adjustedBalance() {
double result = 0;

// 条件检查:账户余额大于0
if (balance > 0) {
// 条件检查:利率和存款期限都大于0
if (interestRate > 0 && duration > 0) {
result = (balance * interestRate * duration) / 100;
}
}

return result;
}
1
2
3
4
5
6
7
8
9
10
11
12
public double adjustedBalance() {

// 条件检查:账户余额不大于0
if (balance <= 0) {
return 0;
}
// 条件检查:利率和存款期限都不大于0
if (interestRate <= 0 || duration <= 0) {
return 0;
}
return (balance * interestRate * duration) / 100;
}

结语

卫语句在代码中的使用可以带来多方面的好处,其中包括:

  • 提高代码可读性: 使用卫语句可以将复杂的条件逻辑拆分为多个简单的条件检查,使得代码更易于理解和维护。每个条件检查都明确地表达了其意图,使得代码的逻辑结构更清晰。

  • 简化代码结构: 卫语句可以减少嵌套的条件逻辑,使得代码结构更加扁平化。这样做不仅使代码更容易阅读,还可以减少错误和提高代码的可维护性。

  • 提前返回: 使用卫语句可以在满足特定条件时提前返回,避免执行后续的代码逻辑,从而提高代码的执行效率。这对于处理边界情况和错误情况尤其有用。

  • 减少bug的产生: 卫语句可以帮助开发者在编写代码时更早地发现潜在的错误和边界情况,从而减少bug的产生。通过提前处理特殊情况,可以使代码更加健壮和可靠。

  • 增强代码的健壮性: 使用卫语句可以有效地防止意外情况的发生,例如空指针异常、除零错误等。通过在代码中加入防御性措施,可以使代码更具健壮性,提高系统的稳定性和可靠性。

总的来说,卫语句是一种简洁、清晰且高效的编程技术,它能够帮助开发者更好地处理复杂的条件逻辑,提高代码的可读性、可维护性和健壮性。

  • 标题: 防卫式编程具体实现——卫语句
  • 作者: HYF
  • 创建于 : 2024-05-31 23:26:32
  • 更新于 : 2024-07-27 21:21:52
  • 链接: https://youfeng.ink/guard-fff9ab860cb8/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
此页目录
防卫式编程具体实现——卫语句