当前位置: 首页 > 科技观察

Web开发应该了解的5种设计模式

时间:2023-03-12 01:21:04 科技观察

什么是设计模式?设计模式是对软件设计和开发过程中反复出现的某些类型问题的通用解决方案。设计模式更多的是指导思想和方法论,而不是现成的代码。当然,每种设计模式在每种语言中都有特定的实现。学习设计模式更多的是理解各种模式的内在思想和解决方案。毕竟这是无数前人经验总结出来的最佳实践,代码实现是加深理解的辅助手段。设计模式用于可重用的代码,使代码更容易被他人理解,并保证代码的可靠性。在这篇文章中,我将介绍JavaScript在实际使用场景中常见的四种设计模式:那个例子。实现方法是判断对象是否有实例。如果已经存在,则不会再次创建。使用场景只适用于业务场景中的一个实例,如弹窗、购物车等。单例模式分为懒惰和饥饿。:惰性风格letShopCar=(function(){letinstance;functioninit(){/*在这里定义单例代码*/return{buy(good){this.goods.push(good);},goods:[],};}return{getInstance:function(){if(!instance){instance=init();}returninstance;},};})();letcar1=ShopCar.getInstance();letcar2=ShopCar.getInstance();car1.buy('orange');car2.buy('apple');console.log(car1.goods);//['orange','apple']console.log(car1===car2);//真饿了么中国风varShopCar=(function(){varinstance=init();functioninit(){/*这里定义了单例代码*/return{buy(good){this.goods.push(good);},goods:[],};}return{getInstance:function(){returninstance;},};})();letcar1=ShopCar.getInstance();letcar2=ShopCar.getInstance();car1.buy('橙色');car2.buy('apple');//['orange','apple']console.log(car1.goods);console.log(car1===car2);//加载类时真正的懒惰风格,不创建实例,类加载速度快,但运行时获取对象速度慢;饿了么中文风格是在类加载的时候初始化的,所以类加载慢,但是对象获取速度快策略模式定义策略模式定义1一系列的算法,封装了各个算法,让它们可以相互替代。实现方法定义了一组可变的策略类来封装具体的算法,定义了一组常量环境类将请求委托给某个策略类。使用场景适用于需要判断多个条件,甚至是复杂条件嵌套的业务场景,可以使用策略模式来提高代码的可维护性和可读性。例如支付和博客权限验证的实现示例//定义几个策略类varPaymentMethodStrategy={BankAccount:function(money){returnmoney>50?money*0.7:money;},CreditCard:function(money){returnmoney*0.8;},Alipay:function(money){returnmoney;},};/*环境类*/varuserPay=function(selectedStrategy,money){returnPaymentMethodStrategy[selectedStrategy](money);};console.log('银行卡支付价格为:'+userPay('BankAccount',100));//70console.log('支付宝支付价格为:'+userPay('Alipay',100));//100console.log('信用卡支付价格为:'+userPay('CreditCard',100));//80观察者模式定义了观察者模式,也叫订阅-发布模式,是对象的行为模式,定义了对象之间一对多的依赖关系,即也就是说,很多观察者和被观察对象之间存在关系,当被观察对象发生变化时,所有的观察者对象都会得到通知,它们都会执行相应的操作。实现方法定义了一组可变的策略类来封装具体的算法,定义了一组常量环境类将请求委托给某个策略类。使用场景适用于业务场景。当一个对象的状态发生变化时,需要自动通知其他人。关联对象,自动刷新对象状态,或者执行对应对象的方法。比如你是老师,需要通知班里的家长,你可以创建一个群(列表)。每次通知一个事件,只需要循环遍历这个列表(群发)即可,不用关心这个列表中有谁。实现实例//创建一个group,保存通知,通知变化后通知每个parent(触发所有观察者对象)classGroup{constructor(){this.message='nonotification';this.parents=[];}getMessage(){returnthis.message;}setMassage(message){this.message=message;this.notifyAllObservers();}notifyAllObservers(){this.parents.forEach((parent)=>{parent.update();});}attach(parent){this.parents.push(parent);}}//观察者,每个父类Parent{constructor(name,group){this.name=name;this.group=group;this.group.attach(this);}update(){console.log(`${this.name}收到通知:${this.group.getMessage()}`);}}letgroup=newGroup();lett1=newParent('李妈妈',group);lett2=newParent('王爸爸',group);lett3=newParent('张爷爷',group);group.setMassage('开家长会');group.setMassage('开运动会');/*李妈妈收到通知:召开家长会王爸爸收到通知:开家长会张爷爷收到通知:开运动会*/decorator模式定义,不改变原有结构和函数,动态装饰一些适用于特殊场景的方法或属性,即增加一些新的功能来增强其某些能力实现方法定义了一组可变策略类来封装特定的算法,定义了一组常量环境类来委托请求到某个策略类,并使用原来的方法保持不变,然后在原方法上挂载其他方法即可满足要求。现有要求;功能解耦,将功能拆分成多个可复用的功能,然后将拆分后的功能挂载到某个功能上,达到同样的效果但增强了复用性。如多孔套接字,机车改装实现示例:constMan=function(){this.run=function(){console.log('running');};};constDecorator=function(old){this.oldAbility=old。run;this.fly=function(){console.log('有飞行能力');};this.newAbility=function(){this.oldAbility();this.fly();};};constman=newMan();constsuperMan=newDecorator(man);superMan.fly();//具有飞行能力的代理模式定义代理模式为某个对象提供代理对象,代理对象控制对原对象的引用.通俗地说,代理模式就是我们生活中常见的中介。实现方法中定义了一个delegator和一个proxy,需要委托的事情都在proxy中完成。在某些情况下,客户类不想或不能直接引用委托对象,代理类对象可以位于客户类和委托对象之间。起到中介作用。代理可以帮助客户端过滤掉一些请求,并延迟创建一些昂贵的对象,直到真正需要它们为止。中介购车、代购、课代表收老师作业示例:classLetter{constructor(name){this.name=name;}}//暗恋小明letXiaoMing={name:'Xiaoming',sendLetter(target){目标。receiveLetter(this.name);},};//代理小花letxiaoHua={receiveLetter(customer){//当然是等小红心情好的时候发情书,之后再创建情书发送情书XiaoHong.listenGoodMood(()=>{XiaoHong.receiveLetter(newLetter(customer+'情书'));});},};//喜欢的对象小红letXiaoHong={name:'小红',receiveLetter(letter){console.log(this.name+'received:'+letter.name);},listenGoodMood(fn){setTimeout(()=>{fn();},1000);},};小明。sendLetter(xiaoHua);//小红收到:小明的情书Proxy是ES6提供的代理,具体出现在proxy的角色中。Vue3.0的响应式数据部分摒弃了Object.defineProperty,改用Proxy。varproxy=newProxy(目标,处理程序);现在用Proxy来模拟另一个场景:为了保护挂科的学生,课代表在拿到全班的成绩单后,才会公布合格者的成绩。对考试成绩有疑问的考生有权在新成绩比以前提高10分后更新成绩。constscoreList={'wang':90,'li':60,'wu':100,}constyyProxy=newProxy(scoreList,{get:function(scoreList,name){if(scoreList[name]>69){console.log('输出分数')returnscoreList[name]}else{console.log('不及格成绩不能公布')},set:function(scoreList,name,val){if(val-scoreList[name]>10){console.log('修改分数')scoreList[name]=val}else{console.log('不能修改结果');}}})yyProxy['wang']=98//不能修改结果yyProxy["li"]=80//修改结果总结我曾经认为设计模式是疯狂的、遥远的软件开发指南。然后我发现我一直在使用它们!我介绍的一些模式在许多应用程序中都有使用。但归根结底,它们只是理论。作为开发者,是否使用取决于使用后是否让代码逻辑更容易实现和维护。作者:johnYu链接:https://juejin.im/post/6859506910652006414来源:掘金