JS设计模式 - 代码质量的高低是素质,学会权衡才是高价值的开发经验

82 阅读2分钟

前言: 设计模式能改变什么,先看一段代码

依次递增的需求

  1. 请求数据渲染页面
  2. 数据缓存,优先取缓存
  3. 增加点击按钮,点击必须请求数据
  4. 离线情况取缓存
// 增加flag参数处理鼠标点击情况
function View(url, data, dom, flag) {
    if (navigator.onLine) {
        // 离线取缓存
    }
    if (localStorage.getItem('list') && !flag) {
        var arr = JSON.parse(localStorage.getItem('list'))
        let html = ``
        arr.forEach((ele, index) => {
            htmlStr += `<li>${ele.name}</li>`
        })
        dom.innerHTml = htmlStr
    } else {
        // 获取数据功能
        $.ajax({
            url,
            params,
            success(json) {
                const arr = JSON.parse(json)
                localStorage.setItem('list', json)
                // 渲染数据
                let html = ``
                arr.forEach((ele, index) => {
                        htmlStr += `<li>${ele.name}</li>`
                })
                dom.innerHTml = htmlStr
            }
        })
    }
}
View('xxx', 'xxx', ul)
// 按钮点击
btn.onclick = () => {
    View('xxx', 'xxx', ul,true)
}

感觉很糟糕,我也写过这样的代码

问题: 后续继续增加需求,还要重新理解一遍代码,增加参数增加判断怎样怎样

使用单一原则的代码

function GetData(callbackArr) {
    this.getData = (url, params) => {
        $.ajax({
            url,
            params,
            success(json) {
                callbackArr.forEach((el) => {
                    el.do(json)
                })
            }
        })
    }
}

// 渲染
function Render(dom) {
    this.do = (data) => {
        let html = ``
        arr.forEach((ele, index) => {
            htmlStr += `<li>${ele.name}</li>`
        })
        dom.innerHTml = htmlStr
    }
}
// 数据缓存
function CacheData(type) {
    this.do = (data) => {
        localStorage.setItem(type, data)
    }
    this.returnCache = () => {
        return localStorage.getItem(type)
    }
}

const oR = new Render(ul)
const oC = new CacheData('list')
const myData = new GetData([oR, oC])
myData.getData('xxxx', 'xxx')
// 增加功能,离线情况,取缓存数据,并且按钮点击也不通过数据请求
// 在线情况,缓存获取数据,点击按钮通过网络获取
if (navigator.onLine) {
    if (oC.returnCache()) {
        oR.do(oC.returnCache())
    } else {
        myData.getData('xxx', xxx)
    }
} else {
    if (oC.returnCache()) {
        oR.do(oC.returnCache())
    }
}
btn.onclick = () => {
    myData.getData('xxx', 'xxx')
}

使用单一设计原则后,逻辑变的很清晰,便于维护和扩展,增加了耦合性但降低了复杂度

设计模式

定义

设计模式(Design Mode)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。就是想出套路做事情。

目的

为了代码的可重用性、让代码更容易被人理解、保证代码的可靠性。设计模式使代码编写真正工程化。

开发时的流程

优先降低复杂度,尽量降低耦合度

  • 利用单一职责原则,开闭原则,里氏代换原则降低复杂度
  • 通过迪米特法则减少耦合度
  • 通过依赖倒置原则消除可以没有的耦合

六大原则

  1. 单一职责原则

  2. 开闭原则:

    • 一个软件实体如类、模块和函数应该对外扩展开放、对修改关闭
    • 面向扩展开放,面向修改关闭,增强代码复用性
  3. 里氏代换原则:

    • 任何基类可以出现的地方,子类一定可以出现,即子类可以扩展弗雷的功能,但不能改变原有的功能
  4. 迪米特法则(最小知道法则)

    • 一个方法传入参数越少越好,降低耦合度的同时也会让复杂度降低
  5. 依赖倒置原则

    • 各对象不依赖于彼此,而依赖于状态,例如VUEX,耦合度和风险函数呈指数型
  6. 接口分离原则

    • 不能一个接口全部实现增删改查

先原则,后模式,代码是一团乱麻,先用单一、开闭、里氏代换分成块,最小知道原则让他们关系变得弱化,最后需要依赖倒置,把没必要的耦合给它消除了

代码质量的高低是素质,学会权衡才是高价值的开发经验,需要权衡时间成本、收益和风险