前言: 设计模式能改变什么,先看一段代码
依次递增的需求
- 请求数据渲染页面
- 数据缓存,优先取缓存
- 增加点击按钮,点击必须请求数据
- 离线情况取缓存
// 增加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)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。就是想出套路做事情。
目的
为了代码的可重用性、让代码更容易被人理解、保证代码的可靠性。设计模式使代码编写真正工程化。
开发时的流程
优先降低复杂度,尽量降低耦合度
- 利用单一职责原则,开闭原则,里氏代换原则降低复杂度
- 通过迪米特法则减少耦合度
- 通过依赖倒置原则消除可以没有的耦合
六大原则
-
单一职责原则
-
开闭原则:
- 一个软件实体如类、模块和函数应该对外扩展开放、对修改关闭
- 面向扩展开放,面向修改关闭,增强代码复用性
-
里氏代换原则:
- 任何基类可以出现的地方,子类一定可以出现,即子类可以扩展弗雷的功能,但不能改变原有的功能
-
迪米特法则(最小知道法则)
- 一个方法传入参数越少越好,降低耦合度的同时也会让复杂度降低
-
依赖倒置原则
- 各对象不依赖于彼此,而依赖于状态,例如VUEX,耦合度和风险函数呈指数型
-
接口分离原则
- 不能一个接口全部实现增删改查
先原则,后模式,代码是一团乱麻,先用单一、开闭、里氏代换分成块,最小知道原则让他们关系变得弱化,最后需要依赖倒置,把没必要的耦合给它消除了
代码质量的高低是素质,学会权衡才是高价值的开发经验,需要权衡时间成本、收益和风险