提到设计模式可能你们会感受有点高大上的感受,其实这个东西的概念很抽象,可是在实际开发中仍是有不少地方可使用设计模式的思想,对咱们的代码进行一次优化。本文旨在介绍一些开发中经常使用的设计模式,经过例子来进行学习,尽可能对概念一带而过。为了讨隔壁前端小姐姐
的崇拜的目光,一块儿学一下吧!前端
概念
:将一个类的接口转化成另一个接口,以知足用户需求,使类(对象)之间的接口的不兼容问题经过适配器得以解决。vue
在工做中,有时为了知足需求,在开发新模块的时候须要对老模块作一个兼容,这时候就须要适配器模式。ios
例如
:ajax
// 参数大于2建议使用对象进行合并
function doSomeThing(obj){
const adapter = {
name:"默认姓名",
color:"red",
size:200,
age:20
}
for (let i in adapter){
adapter[i] = obj[i] || adapter[i];
}
// do some thing
}
复制代码
能够看到这么处理以后咱们不管传入的参数是什么均可以保证对象中拥有这几个属性。避免后续逻辑出错。算法
在vue使用中,咱们一般会将api请求挂载在vue实例上,可是有些老的项目是经过封装ajax请求,在对老项目进行重构时须要将全部的api请求放到axios上或者fetch上。这就可使用适配器模式。axios
// 对fetch 封装伪代码
export default class FetchApi{
static get(url){
return new Promise((resolve,reject)=>{
fetch(url).then(...).catch(err=>reject(err))
})
}
static post(url,data){
return new Promise(...)
}
}
// 在使用时咱们能够这么使用
const res = await FetchApi.get(url) || {};
// 或者
const res = await FetchApi.post(url,params) || {}
// 再看一下原有的接口封装方式 伪代码
function Ajax(type,url,data){
const xhr = new XMLHttpRequest()
...
if(type === 'GET'){
xhr.open('GET',url+"?"+data,true);
xhr.send()
}else if(type === 'POST'){
xhr.open('POST',url,true);
xhr.setRequestHeader("Content-type",'application/x-www-form-urlencoded')
xhr.send(data)
}
...
}
// 调用方式
Ajax("GET",url,data)
复制代码
在这里咱们能够看到新老接口的接口名不同,请求传参也不同。不要紧,使用适配器解决。设计模式
// 伪代码
async function ajaxAdapterr(type,url,data){
let result
if(type === 'GET'){
result = await FetchApi.get(url) || {}
}else if(type === 'POST'){
result = await FetchApi.post(url,data) || {}
}
}
async function Ajax(type,url,data){
await ajaxAdapterr(type,url,data);
}
复制代码
这样就能够对原有的ajax请求变动到fetch上,避免一个个去修改页面中的请求。节省大量了时间能够用来摸鱼。api
概念
:将定义的一组算法封装起来,使其相互之间能够替换。封装的算法具备必定的独立性,不会随客户端的变化而变化。缓存
概念这东西就是善于将人人都懂
的东西描述成人人都不懂
。咱们仍是看实际场景吧。markdown
工做中,相信你们必定写过不少不少的if else判断。当条件愈来愈多的时候,这种书写方式就会变得特别臃肿,那么就用策略模式优化一下吧。
例如
:
function doSomeThing(type){
if(type === 'pre'){
return 100
}else if(type === 'onSale'){
return 200
}else if(type === 'back'){
return 150
}else if(type === 'fresh'){
return 250
}
}
// 逻辑会愈来愈臃肿 用策略模式优化一下
function doSomeThing(type){
const priceType = {
pre(){
return 100
},
onSale(){
return 200
},
back(){
return 150
},
fresh(){
return 250
}
}
return priceType[type]()
}
复制代码
能够看到,在使用策略模式优化以后,代码的映射关系很明确,而且更加的灵活直观,后期的维护只须要去在对象中添加方法便可。帅就一个字,我只说一次。这样的代码哪一个前端小姐姐看了不说棒呢?
概念
:当一个对象的内部状态发生改变时,会致使其行为的改变,这看起来像是改变了对象。
状态模式的概念与策略模式相似,都是封装行为、都经过委托来实现行为分发。可是策略模式里面分发的方法,没有依赖,互相平行,进水不犯河水。而状态模式里,各函数与主体存在必定的关联。
例如
:
自动咖啡机
class Coffee{
constructor(){
this.state ='黑咖啡';
}
stateProcessor = {
american: () => {
console.log("黑咖啡")
},
latte: () => {
this.stateProcessor.american(); // 制做黑咖啡
console.log("加奶")
},
vanillaLatte: () => {
this.stateProcessor.latte();
console.log("加香草🌿糖浆")
},
mocha: () => {
this.stateProcessor.latte();
console.log('加巧克力🍫')
}
}
changeState(state){
this.state = state;
if(!this.stateProcessor[state]){
return console.log("暂无此咖啡")
}
this.stateProcessor[state]()
}
}
const coffee = new Coffee();
coffee.changeState("latte")
复制代码
状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的状况,把状态的判断逻辑转移到表示不一样状态的一系列类中,能够把复杂的判断逻辑简化。
概念
:因为一个对象不能直接引用另外一个对象,因此须要经过代理对象在这两个对象之间起到中介做用。
代理你们可能日常开发中都有涉及到,基本那种代理这里不作介绍,这里介绍一下缓存代理
例如
: 对入参进行求和处理
// addAll方法会对你传入的全部参数作求和操做
const addAll = function() {
console.log('进行了一次新计算')
let result = 0
const len = arguments.length
for(let i = 0; i < len; i++) {
result += arguments[i]
}
return result
}
// 为求和方法建立代理
const proxyAddAll = (function(){
// 求和结果的缓存池
const resultCache = {}
return function() {
// 将入参转化为一个惟一的入参字符串
const args = Array.prototype.join.call(arguments, ',')
// 检查本次入参是否有对应的计算结果
if(args in resultCache) {
// 若是有,则返回缓存池里现成的结果
return resultCache[args]
}
return resultCache[args] = addAll(...arguments)
}
})()
复制代码
能够看到,在入参一致的状况下,只作了一次计算,后续都是从缓存中取值进行返回,这在计算量特别大的状况下将会极大节省时间开销。
概念
: 在不改变原对象的基础上,经过对其进行包装扩展(添加属性或者方法),使得原有对象能够知足更复杂的需求。
例如
: 在审批流中,原需求是审批经过拒绝都放在了一块儿进行了处理,后期增长了需求,在拒绝时须要显示一个弹框输入拒绝缘由
// 原有的审批逻辑
function approvalOrReject(){
// do some thing
}
function rejectShowBox(){
this.approvalOrReject();
this.showMessageBox(); // 显示弹框
}
复制代码
如此一来,咱们就实现了“只添加,不修改”的装饰器模式。实际开发中的装饰器模式用处特别多,你们能够用心去发现~
暂时先总结这些设计模式吧,后续还会继续整理添加,请你们点赞收藏关注咯~
自从用了设计模式,小姐姐都开始对我频频点头了,兄弟们,用起来吧。
因为本人水平有限,文内若有错误欢迎与我联系。