图解你身边的 SOLID 原则 - JS 实例版
S - 单一职责原则
例子
我们假设需要验证一个表单,然后将用户保存到数据库中。
不推荐
/**
* 这个函数的名字就明显违背了单一职责原则
* 对于表单的验证和用户创建被耦合在一起了
* 这样写是不推荐的!
*/
function validateAndSaveUser (req) {
// 调用外部函数来验证用户表单
const isFormValid = validateForm(req.name, req.password, req.email)
// 如果表单合法
if (isFormValid) {
doCreateUser(req.name, req.password, req.email) // 创建用户的具体实现
}
}
推荐
// 验证请求的函数
function validateRequest (req) {
// 调用外部函数来验证用户表单
const isFormValid = validateForm(req.name, req.password, req.email)
// 如果表单合法
if (isFormValid) {
createUser(req) // 在另一个模块中实现
}
}
// 仅仅用来将用户存储到数据库
function createUser (req) {
doCreateUser(req.name, req.password, req.email) // 具体实现代码
}
上面的修改虽然看起来很小,但是将验证逻辑和用户创建逻辑进行了解耦,而用户创建貌似是个会经常更改的功能,这就为将来的修改提供了便利。
O - 开闭原则
例子
假设我们有以下的权限验证函数:
const roles = ["ADMIN", "USER"]
function checkRole (user) {
if (roles.includes(user.role)) {
return true
}
return false
}
// 角色校验
checkRole("ADMIN") // true
checkRole("Savo") // false
如果我们想要添加一个超级管理员,为了不修改之前的代码(或者说我们本来就无法修改遗留代码),我们可以添加一个新增权限函数:
// 此处的代码无法修改!
const roles = ["ADMIN", "USER"]
function checkRole (user) {
if (roles.includes(user.role)) {
return true
}
return false
}
// 此处的代码无法修改!
// 我们可以定义一个函数专门用来新增角色
function addRole (role) {
roles.push(role)
}
// 调用新函数来添加角色
addRole("SUPERUSER")
// 验证角色
checkRole("ADMIN") // true
checkRole("Savo") // false
checkRole("SUPERUSER") // true
L - 里氏替换原则
例子
下面以工程师为例子,初级工程师其实就可以被高级工程师替换掉。(没毛病==)
class Engineer {
constructor (coder) {
this.coder = coder
this.writeCode = function () {
console.log("Coding") // 工程师都会写代码
}
}
// 初级工程师
Simple (coder) {
this.writeCode(coder)
}
// 高级工程师
Pro (coder) {
this.writeCode(coder)
console.log("Design Architecture") // 高级工程师还需要设计架构~
}
}
const a = new Engineer("Savokiss")
a.Simple()
// 输出:
// Coding
a.Pro()
// 输出:
// Coding
// Design Architecture...
I - 接口隔离原则
例子
不推荐
// 什么情况下都进行验证
class User {
constructor (username, password) {
this.initUser(username, password)
}
initUser (username, password) {
this.username = username
this.password = password
this.validateUser()
}
validateUser () {
console.log("验证中...") // 添加验证逻辑
}
}
const user = new User("Savokiss", "123456")
console.log(user)
// 验证中...
// User {
// validateUser: [Function: validateUser],
// username: 'Savokiss',
// password: '123456'
// }
推荐
// 将验证当做一个可选接口
class User {
constructor (username, password, validate) {
this.initUser(username, password, validate)
if (validate) {
this.validateUser()
} else {
console.log("不需要验证逻辑")
}
}
initUser (username, password, validate) {
this.username = username
this.password = password
this.validate = validate
}
validateUser () {
console.log("验证中...")
}
}
// 需要验证的用户
console.log(new User("Savokiss", "123456", true))
// 验证中...
// User {
// validateUser: [Function: validateUser],
// username: 'Francesco',
// password: '123456',
// validate: true
// }
// 不需要验证的用户
console.log(new User("Guest", "guest", false))
// 不需要验证逻辑
// User {
// validateUser: [Function: validateUser],
// username: 'guest',
// password: 'guest',
// validate: false
// }
D - 依赖倒置原则
例子
不推荐
// http 请求依赖了 setState 函数,即依赖了一个细节
http.get("http://address/api/examples", (res) => {
this.setState({
key1: res.value1,
key2: res.value2,
key3: res.value3
})
})
推荐
// http 请求
const httpRequest = (url, state) => {
http.get(url, (res) => state.setValues(res))
}
// 在另一个函数中设置状态
const state = {
setValues: (res) => {
this.setState({
key1: res.value1,
key2: res.value2,
key3: res.value3
})
}
}
// 请求时,将 state 作为抽象注入进去
httpRequest("http://address/api/examples", state)
品牌vi设计公司http://www.maiqicn.com 办公资源网站大全https://www.wode007.com
总结
SOLID 原则的主要目标是让任何软件都应该更容易更改,并且更易于理解。
SOLID 原则同时也让你的代码:
- 更加易于理解
- 更加易于扩展,同时减少 bug
- 隔离抽象和实现
- 更加易于替换实现
- 更加易于测试
好啦~ 希望本文对你有帮助~