一、引言
在编程领域,if - else
语句我们再熟悉不过了。它简单易用,是构建程序逻辑的常用方式。可一旦业务变得复杂起来,大量嵌套的 if - else
代码就会像乱麻一样,把代码的可读性、可维护性和扩展性都搞得一团糟。本文就来好好讲讲怎么用策略模式和合理运用 return
语句,把代码从这团乱麻里解救出来,让代码结构更清晰、更高效。
二、return
语句:简化 if - else
的得力助手
(一)代码瘦身与逻辑明晰
当 if - else
处理复杂业务逻辑时,代码常常会陷入层层嵌套的困境。就拿处理用户数据的函数来说:
function processUserData(user) {
if (user.role === 'admin') {
if (user.status === 'active') {
if (user.permissions.includes('edit')) {
// 执行管理员编辑权限相关操作
// 比如数据库更新、日志记录等复杂操作
console.log('Admin user with edit permission. Performing edit operations...');
// 这里省略具体数据库和日志操作代码
const result = someDatabaseEditFunction(user);
logEditAction(user, result);
} else {
// 管理员无编辑权限处理
console.log('Admin user without edit permission.');
}
} else {
// 非活跃管理员处理
console.log('Inactive admin user.');
}
} else if (user.role ==='moderator') {
// 版主用户处理逻辑
console.log('Moderator user.');
// 可能有审核内容、处理举报等操作
const reviewResult = reviewContent(user);
handleReports(user, reviewResult);
} else {
// 普通用户处理逻辑
console.log('Regular user.');
// 比如显示普通用户界面、限制访问某些功能
showRegularUserInterface(user);
}
}
随着业务拓展,要加新的角色或状态判断,这代码就会越来越臃肿,维护起来特别费劲。
要是用 return
语句优化一下,就大不一样了:
function processUserData(user) {
if (user.role === 'admin' && user.status === 'active' && user.permissions.includes('edit')) {
// 执行管理员编辑权限相关操作
// 比如数据库更新、日志记录等复杂操作
console.log('Admin user with edit permission. Performing edit operations...');
// 这里省略具体数据库和日志操作代码
const result = someDatabaseEditFunction(user);
logEditAction(user, result);
return;
}
if (user.role === 'admin' && user.status === 'active') {
// 管理员无编辑权限处理
console.log('Admin user without edit permission.');
return;
}
if (user.role === 'admin') {
// 非活跃管理员处理
console.log('Inactive admin user.');
return;
}
if (user.role ==='moderator') {
// 版主用户处理逻辑
console.log('Moderator user.');
// 可能有审核内容、处理举报等操作
const reviewResult = reviewContent(user);
handleReports(user, reviewResult);
return;
}
// 普通用户处理逻辑
console.log('Regular user.');
// 比如显示普通用户界面、限制访问某些功能
showRegularUserInterface(user);
}
这样一改,每个条件分支的处理目的都很清楚,阅读代码时能轻松理解,维护起来也方便多了。要改某个角色或状态的处理逻辑,能很快找到对应的代码块,不会被其他无关判断干扰。
(二)性能优化:提前 “退场” 机制
在数据处理和验证场景里,return
语句能很好地提升函数执行效率。比如用户注册信息验证函数:
function validateUserRegistration(userData) {
if (!userData.username) {
return false;
}
if (!userData.email ||!isValidEmailFormat(userData.email)) {
return false;
}
if (!userData.password || userData.password.length < 8) {
return false;
}
// 其他验证条件,像手机号码格式验证等
if (!userData.phoneNumber ||!isValidPhoneNumberFormat(userData.phoneNumber)) {
return false;
}
// 假设还有更多复杂验证,比如检查用户名是否已存在数据库
// const usernameExists = checkUsernameExists(userData.username);
// if (usernameExists) {
// return false;
// }
// 主要逻辑代码,理想情况
return true;
}
function isValidEmailFormat(email) {
// 简单的邮箱格式验证逻辑
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/;
return emailRegex.test(email);
}
function isValidPhoneNumberFormat(phoneNumber) {
// 简单的手机号码格式验证逻辑
const phoneNumberRegex = /^[+]?[(]?[0-9]{3}[)]?[-\s.]?[0-9]{3}[-\s.]?[0-9]{4,6}$/;
return phoneNumberRegex.test(phoneNumber);
}
要是用户名没填,函数马上返回 false
,就不用再验证邮箱、密码、手机号等了,节省了计算资源。处理大量注册请求或复杂对象验证时,能大幅缩短函数执行时间,提升程序整体性能。
三、策略模式:应对复杂逻辑的优雅方案
(一)策略模式概述
策略模式,简单说就是把能互相替换的算法分别封装成独立的对象。这样一来,算法的变化就和使用算法的客户端代码分开了,系统灵活性和扩展性都大大增强。
(二)场景实例:电商商品促销计价系统
1. 传统 if - else
实现的困境
在电商商品计价系统里,按不同促销活动算商品总价,用传统 if - else
结构实现的话,代码会变得很糟糕。比如:
function calculateProductPrice(product, promotion) {
let totalPrice = product.price * product.quantity;
if (promotion === 'discount_10_percent') {
totalPrice *= 0.9;
} else if (promotion === 'buy_one_get_one_free') {
const freeItems = Math.floor(product.quantity / 2);
totalPrice = (product.quantity - freeItems) * product.price;
} else if (promotion ==='spend_more_save_more') {
if (totalPrice >= 100 && totalPrice < 200) {
totalPrice *= 0.95;
} else if (totalPrice >= 200) {
totalPrice *= 0.9;
}
} else if (promotion === 'fixed_discount_amount') {
totalPrice -= 10;
}
// 可能还有更多促销类型判断
// 理想情况,主逻辑
return totalPrice;
}
促销活动类型越多,if - else
语句就越长,代码复杂度直线上升。不仅难读懂,维护也麻烦。加个新促销策略,就得在 calculateProductPrice
函数里大改,很容易改错其他促销策略的计算逻辑。
2. 策略模式的 “救赎”
用策略模式重构一下,先定义个策略对象:
const promotionStrategies = {
discount_10_percent: function (product) {
return product.price * product.quantity * 0.9;
},
buy_one_get_one_free: function (product) {
const freeItems = Math.floor(product.quantity / 2);
return (product.quantity - freeItems) * product.price;
},
spend_more_save_more: function (product) {
let totalPrice = product.price * product.quantity;
if (totalPrice >= 100 && totalPrice < 200) {
return totalPrice * 0.95;
} else if (totalPrice >= 200) {
return totalPrice * 0.9;
}
return totalPrice;
},
fixed_discount_amount: function (product) {
return product.price * product.quantity - 10;
}
};
function calculateProductPrice(product, promotion) {
if (!promotionStrategies[promotion]) {
return product.price * product.quantity;
}
return promotionStrategies[promotion](product);
}
重构后,每个促销策略都在 promotionStrategies
对象里独立成一个函数。加新促销策略时,只要在这个对象里加个属性函数就行,不用改 calculateProductPrice
函数的主体逻辑,遵循了开闭原则,系统扩展性变强,能轻松应对促销策略的变化。
四、return
语句与策略模式的优缺点及使用场景深度剖析
(一)return
语句
优点 :
- 简洁代码,清晰逻辑 :
return
语句能减少代码嵌套,让代码结构简洁。遇到条件满足就返回,逻辑流程清晰,阅读代码时能快速理解意图,降低认知负担。 - 提升性能,节省资源 :在数据处理和验证场景,
return
语句可提前结束函数,避免不必要计算,处理大量数据或复杂对象时能显著提升性能,节省计算资源。
- 简洁代码,清晰逻辑 :
缺点 :
- 应对复杂逻辑乏力 :处理简单条件判断还行,面对复杂业务逻辑,
return
语句会让代码碎片化,缺乏整体性,理解和维护大型项目时容易迷失在众多返回点中。 - 可维护性存隐患 :复杂条件判断里,
return
语句多了会让代码执行路径复杂难追踪调试。修改扩展代码时,得小心处理每个return
影响范围,容易出错,多人协作开发时还可能因使用习惯差异导致代码风格不一致和逻辑冲突。
- 应对复杂逻辑乏力 :处理简单条件判断还行,面对复杂业务逻辑,
使用场景 :
- 数据验证显身手 :数据验证场景,如用户输入数据、数据传输完整性验证等,
return
语句可快速发现问题返回错误信息,防止错误数据扩散,保障后续处理流程正常。 - 简单状态判断好帮手 :判断对象简单状态,如是否为空、是否初始化、是否满足简单条件等,
return
语句能快速响应,避免if - else
嵌套,提高代码执行效率和可读性。 - 确保主要逻辑代码始终位于底部 :这样可以减少逻辑处理的复杂性。
- 数据验证显身手 :数据验证场景,如用户输入数据、数据传输完整性验证等,
(二)策略模式
优点 :
- 无限扩展新策略 :策略模式下,每个策略独立封装。添加新策略时,只需插入新模块,无需大幅修改原有核心逻辑,遵循开闭原则,系统能轻松适应业务变化,满足多样需求。
- 代码复用价值高 :策略模式中的策略函数可在不同场景或模块复用,减少代码冗余,避免重复开发,提高代码一致性和稳定性,确保相同策略在不同场景效果相同。
- 结构清晰易维护 :策略模式把不同策略分开,代码结构有序。每个策略专注特定算法或行为,互不干扰且协同工作。维护和理解代码时,能快速定位策略代码,不受其他代码干扰,提高开发效率和质量。
缺点 :
- 策略管理变复杂 :策略数量增多时,管理难度加大。比如大型电商系统有很多促销策略,维护
promotionStrategies
这样的策略对象会很困难,要花大量精力保证策略正确性、独立性和兼容性。 - 客户端决策压力大 :策略模式中,客户端要选合适策略,这增加了客户端的复杂性和决策负担。如果客户端对策略不够了解,可能会选错策略,影响系统功能。而且,当策略变化时,客户端代码可能也需要相应修改,增加了维护成本。
- 策略管理变复杂 :策略数量增多时,管理难度加大。比如大型电商系统有很多促销策略,维护
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。