• 图解你身边的 SOLID 原则


    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
    • 隔离抽象和实现
    • 更加易于替换实现
    • 更加易于测试

    好啦~ 希望本文对你有帮助~

  • 相关阅读:
    bzoj4804
    bzoj2962
    bzoj4827
    bzoj2553
    bzoj3611
    BZOJ 1636: [Usaco2007 Jan]Balanced Lineup
    BZOJ 1635: [Usaco2007 Jan]Tallest Cow 最高的牛
    BZOJ 1634: [Usaco2007 Jan]Protecting the Flowers
    BZOJ 1631: [Usaco2007 Feb]Cow Party
    BZOJ 2582: [Usaco2012Jan]Bovine Alliance
  • 原文地址:https://www.cnblogs.com/xiaonian8/p/13696120.html
Copyright © 2020-2023  润新知