Cet article vous apporte des connaissances pertinentes sur les modèles de conception en JavaScript, notamment le modèle singleton, le modèle de combinaison, le modèle d'observateur, etc. J'espère qu'il vous sera utile.
Le Design Pattern est un ensemble de solutions optimales conçues pour résoudre un certain problème.
Orienté objet - faites plus attention aux objets - trouvez la meilleure façon de définir les objets et d'ajouter des propriétés et des méthodes à chaque objet
La meilleure solution trouvée - est un modèle de conception
Pour différents problèmes, nous aurons différents La meilleure solution - Modèles de conception
Modèles de conception courants :
Connexion à la base de données - plusieurs fonctions doivent faire fonctionner la base de données - reconnecter la base de données - 1000 fonctions, se connecter à la base de données 1000 fois
Fonction d'enregistrement, chaque inscription doit faire fonctionner la base de données - 1000 en même temps heure Les individus s'inscrivent
La base de données MySQL a une limite de connexion : elle ne peut prendre en charge qu'un maximum de 200 connexions en même temps
Nous nous connectons à la base de données une fois, obtenons une connexion et exploitons la base de données plusieurs fois. pour le faire fonctionner
Comment faire fonctionner, laissez plusieurs exécutions d'instructions de base de données utiliser la même connexion - nous pouvons concevoir un modèle de conception
Modèle de conception : définissez une classe, cette nouvelle classe obtiendra une connexion, et chaque fois qu'une instruction de base de données est exécuté à l'avenir, vous pourrez utiliser cette classe à partir d'Obtenir une connexion depuis
Mode Singleton : vous ne pouvez obtenir qu'un seul objet d'une classe - peu importe le nombre de fois que vous utilisez cette classe, tous les objets de connexion finalement obtenus sont le même objet
Laissez tous les objets créés par une classe, toutes les propriétés et méthodes à l'intérieur sont exactement les mêmes. Par exemple, encapsulez une classe et placez certaines fonctions d'exploitation couramment utilisées comme méthodes. À l'avenir, le même objet sera utilisé pour appeler ces méthodes à chaque fois. Normalement, chaque objet créé par une classe est différent.
class Carousel{ }var a = new Carousel();var b = new Carousel();console.log(a === b); // false
Le mode singleton consiste à rendre les deux objets identiques, c'est-à-dire qu'une classe n'aura toujours qu'un seul objet instance
var single = (function(){ class Carousel{ } var res = undefined; return function(){ if(!res){ res = new Carousel(); } return res; }})();var s1 = single();var s2 = single();console.log(s1 === s2); // true
La variable P exposée aux variables globales provoquera une pollution globale
Utilisez des fermetures pour résoudre chaque problème. problème de redéfinition de p
Le code de base du mode singleton :
function Person(){}function fn(Person){ var p; return function(){ if(!p){ p = new Person; } return p; }}var f = fn(Person)var p1 = f()var p2 = f()
Le scénario d'application du mode singleton se trouve dans la bibliothèque de l'outil d'encapsulation.
Exemple : Encapsuler et encapsuler une bibliothèque d'outils
Application en mode Singleton Encapsuler une bibliothèque d'outils工具库中会有很多的方法 - 方法每次的使用 应该是同一个对象使用的,而不是应该每次都有一个新对象在使用工具
// var t = new Tool; // t.setCookie('username', 'zs', 20); const Tool = (function () { class Tool { constructor() { if (window.getComputedStyle) { this.flag = true; } else { this.flag = false; } } /获取节点属性 getStyle(ele, attr) { if (this.flag) { return window.getComputedStyle(ele)[attr]; } else { return ele.currentStyle[attr]; } } getStyle(ele, attr) { 尝试一段代码 不知道会不会报错 尝试成功 后面代码没有什么事 尝试失败 会报错 被cathch 捕获到 会将错误信息放到err参数里 catch{} 里可以处理这个错误 也可以不处理这个错误对上面的错误代码进行补救 错误不会再浏览器里报错 try { return window.getComputedStyle(ele)[attr]; } catch (err) { return ele.currentStyle[attr]; } } // 设置节点css属性 setStyle(ele, styleObj) { for (let attr in styleObj) { ele.style[attr] = styleObj[attr]; } } // 设置cookie setCookie(key, value, second, path = '/') { let data = new Date(); date.setTime(date.getTime() - 8 * 3600 * 1000 + second * 1000); document.cookie = `${key}=${value};expires=${date};path=${path}`; } } var tool; return (function () { if (!tool) { tool = new Tool(); } return tool; })(); })();
class Carousel{ init(){ console.log("轮播图开始运行"); }}class Tab{ init(){ console.log("选项卡开始运行"); }}class Enlarge{ init(){ console.log("放大镜开始运行"); }}// 这3个类要运行起来需要各自实例化,并调用每个类中的init方法,此时就可以使用组合模式做一个启动器
Lanceur de production en mode combiné :
class Starter{ constructor(){ this.arr = []; // 定义一个数组 } add(className){ this.arr.push(className); // 将这个多个类放进数组 } run(){ for(var i=0;i<this.arr.length><p></p>1.4 Mode publication et abonnement<hr> <h3>https://blog.csdn.net/weixin_44070254/article/details/117574565?spm=1001.2014.3001.5501</h3> <p>Certaines personnes s'abonnent et d'autres publier </p> Modèle d'abonnement de publication : un observateur est nécessaire. Une personne observée est nécessaire. Si l'observateur constate que l'état de l'objet observé a changé, il doit définir une tâche : <p></p> <pre class="brush:php;toolbar:false">class Observer{ // 观察者有名字和任务 constructor(name,task){ this.name = name this.task = task }}// 定义班主任var bzr = new Observer('班主任',function(state){ console.log("因为"+state+",所以"+this.name+"罚站");})// 定义了一个年级主任var zr = new Observer('年级主任',function(state){ console.log("因为"+state+",所以"+this.name+"要找班主任");})// 被观察者class Subject{ // 有自己的状态 constructor(state){ this.state = state // 观察者们 this.observer = []; } // 添加被观察者 add(...arr){ this.observer = this.observer.concat(arr) } // 改变状态 changeSate(state){ this.state = state // 触发观察者的任务 for(let i=0;i<this.observer.length><br>Modèle d'observateur, également connu. comme modèle de publication-abonnement. Cela signifie qu'une personne surveille constamment une certaine chose lorsque la chose est sur le point d'exécuter un certain comportement, la personne notifiera une fonction pour exécuter l'opération du comportement. <br>Exemple : Une fois le code de l'événement écrit, cet événement surveille en permanence le comportement de l'utilisateur sur la page. Une fois que l'utilisateur déclenche cet événement, une fonction est appelée pour gérer l'événement. <p></p> <pre class="brush:php;toolbar:false">p.addEventListener("click",function(){}); // 这个事件写好以后,就一直在页面中监控用户行为,用户点击这个元素的时候,就调用函数
Besoin d'une méthode pour gérer la liaison d'événement.
class watch{ bind(){ } touch(){ } unbind(){ }}var w = new watch();
var w = new watch();w.bind("cl",a); // 给w对象绑定cl事件类型,执行a函数w.bind("cl",b); // 给w对象绑定cl事件类型,执行b函数function a(){ console.log("事件处理函数a");}function b(){ console.log("事件处理函数b");}
constructor(){ this.obj = {} // 存储格式:{事件类型:[函数1,函数2]}}bind(type,handle){ this.obj[type] = [handle]; // 对象存储方式{"cl":[a]}}
bind(type,handle){ if(!this.obj[type]){ this.obj[type] = [handle]; // 对象存储方式{"cl":[a]} }else{ this.obj[type].push(handle); } }
.
绑定后的存储结果 |
---|
触发这个事件需要传入触发哪个事件类型
touch(type){ // 首先要判断,这个事件类型是否绑定,没有绑定不能触发 if(!this.obj[type]){ return false; }else{ // 将这个事件的所有绑定的处理函数一起调用 for(var i=0;i<this.obj><p>测试:</p> <table> <thead><tr class="firstRow"><th>触发测试</th></tr></thead> <tbody> <tr><td><img src="https://img.php.cn/upload/article/000/000/067/723219bbf42dba49705fd0fe49beab7d-1.png" alt="Explication classique JavaScript des modèles de conception (exemples détaillés)"></td></tr> <tr><td><br></td></tr> </tbody> </table> <p>这两个处理函数都没有参数,如果要传入参数的时候该怎么处理?</p> <p>触发事件的时候就要传入实参</p> <pre class="brush:php;toolbar:false">w.touch("cl","张三",20);
触发事件的方法就应该处理这些参数
touch(type,...arr){ // 因为参数不定长,所以使用合并运算符 // 首先要判断,这个事件类型是否绑定,没有绑定不能触发 if(!this.obj[type]){ return false; }else{ // 处理参数:模拟系统事件的参数事件对象,将所有参数都集中在一个对象中 var e = { type:type, args:arr } // 将这个事件的所有绑定的处理函数一起调用 for(var i=0;i<this.obj><p>添加一个带参数的处理函数,并触发事件执行:</p> <pre class="brush:php;toolbar:false">w.bind("cl",c); // 给w对象绑定cl事件类型,执行c函数w.touch("cl","张三",20);function c(e){ console.log("我是处理函数c,打印:姓名"+e.name+",年龄"+e.age);}
结果:
带参数的处理函数处理结果 |
---|
解绑也需要知道解绑的事件类型和处理函数
unbind(type,handle){ // 先判断是否绑定了这个事件 if(!this.obj[type]){ return false; }else{ // 从数组中将这个处理函数删除 for(var i=0;i<this.obj><p>解绑测试:</p> <table> <thead><tr class="firstRow"><th>解绑测试结果</th></tr></thead> <tbody> <tr><td><img src="https://img.php.cn/upload/article/000/000/067/723219bbf42dba49705fd0fe49beab7d-3.png" alt="Explication classique JavaScript des modèles de conception (exemples détaillés)"></td></tr> <tr><td><br></td></tr> </tbody> </table> <p>如果绑定事件的时候使用的匿名函数,就无法进行解绑了,所以再添加一个解绑事件所有处理函数的方法:</p> <pre class="brush:php;toolbar:false">clear(type){ if(!this.obj[type]){ return false; }else{ // 直接从对象中将这个属性删除 delete this.obj[type]; } }
观察者模式跟发布订阅模式不一样的地方在于,要有观察者和被观察者。
创建观察者:
// 创建观察者class Observer{ // 观察者有姓名和技能 - 技能是一个函数 constructor(name,skill){ this.name = name; this.skill = skill }}// 创建观察者var bzr = new Observer('班主任',function(state){ console.log('因为'+state+'叫家长')})var xz = new Observer('校长',function(state){ console.log('因为'+state+'叫班主任')})console.log(bzr,xz)
创建被观察者:
// 创建被观察者 class Subject{ // 被观察者有状态 和 观察者列表 constructor(state){ this.state = state this.observers = [] } // 添加观察者 addObserver(observer){ var index = this.observers.findIndex(v=>v === observer) if(index{ v.skill(this.state) }) } } // 删除观察者 delObserver(observer){ var index = this.observers.findIndex(v=>v === observer) if(index>=0){ this.observers.splice(index,1) } } } // 创建被观察者 var xm = new Subject('学习') // 添加观察者 xm.addObserver(bzr) xm.addObserver(xz) xm.addObserver(bzr) console.log(xm) // 改变状态 xm.setState('玩游戏')
一个问题有多种解决方案,且随时还可以有更多的解决方案,就是策略模式。例如:一个商品在售卖的时候,会有多种折扣方式,慢100减10元,满200减30元等…
商品活动:
满100减10
满200减30
满300打8折
策略模式:将折扣放在闭包中保存起来 - 通过闭包对折扣进行增删改查操作
正常的函数表达方式:
function fn(type,price){ if(type === '100_10'){ return price -= 10 }else if(type === '200_30'){ return price -= 0 }else{ return '没有这种折扣' }}fn('100_10',160)
这种方式,在添加折扣或删除折扣的时候总是需要修改原函数。
策略模式代码:
var calcPrice = (function(){ // 以闭包的形式存储折扣数据 var sale = { '100_10':function(price){ return price -= 10 }, '200_20':function(price){ return price -= 20 } } function calcPrice(type,price){ // 闭包中使用折扣 if(type in sale){ return sale[type](price) }else{ return '没有这个折扣' } } // 折扣函数添加属性 - 添加折扣 calcPrice.add = function(type,fn){ if(type in sale){ console.log('折扣存在') }else{ sale[type] = fn } } // 删除折扣 calcPrice.del = function(type){ if(type in sale){ delete sale[type] }else{ console.log('折扣不存在') } } return calcPrice})()var p = calcPrice('100_10',200)calcPrice.add('200_320',function(price){ return price -= 50})calcPrice.del('200_330')var p = calcPrice('200_320',200)console.log(p)
相关推荐:javascript学习教程
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!