自解释代码
· 阅读需 2 分钟
summary
- 使用命名常量而非晦涩的错误代码 | Using named constants instead of cryptic error codes
- 将复杂逻辑抽离成独立函数 | Extracting complex logic and putting it in its own function
- 运用短路求值使代码流程线性化 | Using short-circuit evaluation to make the code flow linear
- 引入类型注解辅助静态检查与实时编码反馈 | Introducing type annotations to help with static type checking and real-time coding feedback
original code
async function createUser(user) {
if (!validateUserInput(user)) {
throw new Error('u105');
}
const rules = [/[a-z]{1,}/, /[A-Z]{1,}/, /[0-9]{1,}/, /\W{1,}/];
if (user.password.length >= 8 && rules.every((rule) => rule.test(user.password))) {
if (await userService.getUserByEmail(user.email)) {
throw new Error('u212');
}
} else {
throw new Error('u201');
}
user.password = await hashPassword(user.password);
return userService.create(user);
}
命名常量与单一职责原则
const err = {
userValidationFailed: 'u105',
userExists: 'u212',
invalidPassword: 'u201',
};
function isPasswordValid(password) {
const rules = [/[a-z]{1,}/, /[A-Z]{1,}/, /[0-9]{1,}/, /\W{1,}/];
return password.length >= 8 && rules.every((rule) => rule.test(password));
}
async function createUser(user) {
if (!validateUserInput(user)) {
throw new Error(err.userValidationFailed);
}
if (isPasswordValid(user.password)) {
if (await userService.getUserByEmail(user.email)) {
throw new Error(err.userExists);
}
} else {
throw new Error(err.invalidPassword);
}
user.password = await hashPassword(user.password);
return userService.create(user);
}
短路求值
function throwError(error) {
throw new Error(error);
}
async function createUser(user) {
validateUserInput(user) || throwError(err.userValidationFailed);
isPasswordValid(user.password) || throwError(err.invalidPassword);
!(await userService.getUserByEmail(user.email)) || throwError(err.userExists);
user.password = await hashPassword(user.password);
return userService.create(user);
}