您现在的位置是:主页 > news > 揭阳装修网站建设/网站推广上首页
揭阳装修网站建设/网站推广上首页
admin2025/5/22 13:57:29【news】
简介揭阳装修网站建设,网站推广上首页,北京响应式网站建设推荐,企业品牌网站建设价格策略模式 定义一系列的算法,把它们一个个封闭起来,并且使他们可以相互替换。 举例:处理商店促销类型 prePrice - 处理预热价 onSalePrice - 处理大促价 backPrice - 处理返场价 freshPrice - 处理尝鲜价 askPrice - 分发询价逻辑实现&…
策略模式
定义一系列的算法,把它们一个个封闭起来,并且使他们可以相互替换。
举例:处理商店促销类型
prePrice - 处理预热价
onSalePrice - 处理大促价
backPrice - 处理返场价
freshPrice - 处理尝鲜价
askPrice - 分发询价逻辑
实现:原本全部放在askPrice,并通过ifelse分支处理每种情况, 改为封装每一个单独功能
但还是存在缺点:没有实现“对扩展开放,对修改封闭”的效果。
// 处理预热价
function prePrice(originPrice) {if(originPrice >= 100) {return originPrice - 20} return originPrice * 0.9
}// 处理大促价
function onSalePrice(originPrice) {if(originPrice >= 100) {return originPrice - 30} return originPrice * 0.8
}// 处理返场价
function backPrice(originPrice) {if(originPrice >= 200) {return originPrice - 50}return originPrice
}// 处理尝鲜价
function freshPrice(originPrice) {return originPrice * 0.5
}function askPrice(tag, originPrice) {// 处理预热价if(tag === 'pre') {return prePrice(originPrice)}// 处理大促价if(tag === 'onSale') {return onSalePrice(originPrice)}// 处理返场价if(tag === 'back') {return backPrice(originPrice)}// 处理尝鲜价if(tag === 'fresh') {return freshPrice(originPrice)}
}
策略模式实现:对象映射
// 询价函数
function askPrice(tag, originPrice) {return priceProcessor[tag](originPrice)
}
// 定义一个询价处理器对象
const priceProcessor = {pre(originPrice) {if (originPrice >= 100) {return originPrice - 20;}return originPrice * 0.9;},onSale(originPrice) {if (originPrice >= 100) {return originPrice - 30;}return originPrice * 0.8;},back(originPrice) {if (originPrice >= 200) {return originPrice - 50;}return originPrice;},fresh(originPrice) {return originPrice * 0.5;},
};
加入添加一个新人价格
priceProcessor.newUser = function (originPrice) {if (originPrice >= 100) {return originPrice - 50;}return originPrice;
}
总结:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
一个基于策略模式的程序至少由两部分组成。第一个部分是一组策略类,策略类封装了具体的算法,负责具体的计算过程。第二个部分是环境类context,comtext接受客户的请求,随后把请求委托给某一个策略类。
算法,就是我们这个场景中的询价逻辑,它也可以是你任何一个功能函数的逻辑;“封装”就是把某一功能点对应的逻辑给提出来;“可替换”建立在封装的基础上,只是说这个“替换”的判断过程,咱们不能直接怼 if-else,而要考虑更优的映射方案。
代理模式
代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的访问。
代理模式在前端中比较常用的虚拟代理和缓存代理。
为什么要使用代理模式
中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。
开闭原则,增加功能:代理类除了是客户类和委托类的中介之外,我们还可以通过给代理类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代理类而不需要再修改委托类,符合代码设计的开闭原则。代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后对返回结果的处理等。代理类本身并不真正实现服务,而是同过调用委托类的相关方法,来提供特定的服务。真正的业务功能还是由委托类来实现,但是可以在业务功能执行的前后加入一些公共的服务。例如我们想给项目加入缓存、日志这些功能,我们就可以使用代理类来完成,而没必要打开已经封装好的委托类
保护代理:
用于控制不同权限的对象对目标对象的访问,但是在js并不容易实现保护代理,因为我们无法判断谁访问了某个代理。
虚拟代理:
- 虚拟代理把一些开销很大的对象,延迟到真正需要它的时候才去创建。
- 虚拟代理的特点是,代理类和真正的类都暴露了同样的接口,这样对于调用者来说是无感的。
提到虚拟代理,其最具代表性的例子就是图片预加载。预加载主要是为了避免网络延迟、或者图片太大引起页面长时间留白的问题。通常的解决方案是先给 img 标签展示一个占位图,然后创建一个 Image 实例,让这个实例的 src 指向真实的目标图片地址,当其真实图片加载完成之后,再将 DOM 上的 img 标签的 src 属性指向真实图片地址。
class MyImg {static imgNode = document.createElement("img")constructor(selector) {selector.appendChild(this.imgNode);}setSrc(src) {this.imgNode = src}
}class ProxyMyImg {static src = 'xxx本地预览图地址loading.gif'constructor(selector) {this.img = new Imagethis.myImg = new MyImg(selector)this.myImg.setSrc(this.src)}setSrc(src) {this.img.src = srcthis.img.onload = () => {this.myImg.setSrc(src)}}
}const img = new ProxyMyImg(document.body)
img.setSrc('xxx')
缓存代理:
缓存代理可以为一些开销大的运算结果提供暂时的缓存,在下次运算时,如果传递进来的参数跟之前一致,则可以直接返回缓存好的运算结果。
const mult = (...args) => {console.log('multing...')let res = 1args.forEach(item => {res*=item})return res
}
const proxyMult = (() => {const cache = {}return (...args) => {const key = [].join.call(args, ',')if (key in cache) {return cache[args]}return cache[key] = mult.apply(null, args)}
})()
proxyMult(1,2,3,4)// multing... 24
proxyMult(1,2,3,4)//24
Proxy:ES6新增了代理类Proxy
语法
const p = new Proxy(target, handler)
- target 要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
- handler 一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。
const mult = (args) => {console.log('multing...')let res = 1args.forEach(item => {res*=item})return res
}const handler = {cache: {},apply: function(target, thisArg, args) {const key = [].join.call(args, ',')if(key in this.cache) {return this.cache[key]}return this.cache[key] = target(args)}
}
const proxyMult = new Proxy(mult, handler)
proxyMult(1,2,3,4)
//multing...
//24
proxyMult(1,2,3,4)
//24