Heim > Artikel > Web-Frontend > Gängige Entwurfsmuster in JS
Wenn in großen Einzelseitenanwendungen die Komplexität ein bestimmtes Niveau erreicht, gibt es kein geeignetes Entwurfsmuster für die Entkopplung, und die anschließende Entwicklung wird schwierig zu starten sein.
Das Entwurfsmuster dient genau der Entkopplung.
Der Kern des Singleton-Musters besteht darin, sicherzustellen, dass es nur eine Instanz gibt und globalen Zugriff bereitzustellen.
Erfüllen Sie das „Prinzip der Einzelverantwortung“: Verwenden Sie den Proxy-Modus, bestimmen Sie nicht, ob der Singleton im Konstruktor erstellt wurde;
Erfüllen Sie das Faulheitsprinzip
Das Anmeldefenster öffnet sich.
var getSingle = function (fn) { var res; return function() { return res || (res = fn.apply(this, arguments)); } } var createPopup() { var p = document.createElement('p'); p.innerHTML = "Login window"; p.style.display = "none"; document.body.appendChild(p); return p; } var createLoginPopup = getSingle(createPopup); //create popup p here by using a given function, 满足两个原则 document.getElementById("loginBt").onclick = function() { var popup = createLoginPopup(); pop.style.display = "block"; }
/** * 构造一个动物的函数 */ function Animal(name, color){ this.name = name; this.color = color; this.getName = function(){ return this.name; } } // 实例一个对象 var cat = new Animal('猫', '白色'); console.log( cat.getName() );
function Person(){ } Person.prototype.name = "bill"; Person.prototype.address = "GuangZhou"; Person.sayName = function (){ alert(this.name); } var person1 = new Person(); var person2 = new Person(); //测试代码 alert(person1.name); // bill alert(person2.name); // bill person1.sayName(); //bill person2.sayName(); //bill person1.name = "666"; alert(person1.name); // 666 alert(person2.name); // bill person1.sayName(); //666 person2.sayName(); //bill
/** * 混合模式 = 原型模式 + 构造函数模式 */ function Animal(name, color){ this.name = name; this.color = color; console.log( this.name + this.color) } Animal.prototype.getInfo = function(){ console.log('名称:'+ this.name); } function largeCat(name, color){ Animal.call(null, name, color); this.color = color; } largeCat.prototype = create(Animal.prototype); function create (parentObj){ function F(){} F.prototype = parentObj; return new F(); }; largeCat.prototype.getColor = function(){ return this.color; } var cat = new largeCat("Persian", "白色"); console.log( cat )
Factory: Die Funktion generiert intern das b-Objekt und gibt es zurück.
1. function a(name){ var b = new object(); b.name = name; b.say = function(){ alert(this.name); } return b } 2. function Animal(opts){ var obj = new Object(); obj.name = opts.name; obj.color = opts.color; obj.getInfo = function(){ return '名称:'+obj.name +', 颜色:'+ obj.color; } return obj; } var cat = Animal({name: '波斯猫', color: '白色'}); cat.getInfo();
Die Idee eines einfachen Fabrikmusters besteht darin, Objekte zu erstellen und verschiedene Klassen zu instanziieren; Sie müssen nur ein Objekt erstellen und dann eine große Anzahl davon verwenden Methoden und Eigenschaften dieses Objekts und schließlich das Objekt zurückgeben
//basketball base class var Baseketball = function(){ this.intro = 'baseketball is hotting at unitedstates'; } Baseketball.prototype = { getMember : function(){\ console.log('each team needs five players'); }, getBallSize : function(){ console.log('basketball is big'); } } //football base class var Football = function(){ this.intro = 'football is popular at all of the world'; } Football = function(){ getMember = function(){ }, getBallSize = function(){ } } //sport factory var SportsFactory = function(name){ switch(name){ case 'NBA': return new Baseketball(); case 'wordCup': return new Football(); } } //when you want football var football = SportsFactory('wordCup'); console.log(football); console.log(football.intro); football.getMember();
Dekorationsmuster
Definieren Sie gegenseitig austauschbare Algorithmen und kapseln Sie sie ein.
Entspricht dem Offen-Geschlossen-Prinzip: Wenn Sie den verwendeten Algorithmus ändern möchten, müssen Sie nicht tief in die Funktion einsteigen, um ihn zu ändern , Sie müssen nur die Strategieklasse ändern;
Trennen Sie die Implementierung und Verwendung des Algorithmus, um die Wiederverwendbarkeit des Algorithmus zu verbessern;
Vermeiden Sie mehrere bedingte Auswahlanweisungen durch Kombination, Delegation und Polymorphismus.
Animationen an, um unterschiedliche Beschleunigungseffekte zu erzielen.
Im Allgemeinen in zwei Teile unterteilt: Strategietyp und Umgebungstyp. Die Strategieklasse wird zur Kapselung verschiedener Algorithmen verwendet und ist für den spezifischen Berechnungsprozess verantwortlich. Die Umgebungsklasse ist dafür verantwortlich, Benutzeranfragen zu empfangen und die Anfragen einer bestimmten Strategieklasse anzuvertrauen. Da die von jeder Strategieklasse implementierten Algorithmen und Berechnungsergebnisse unterschiedlich sind, die Methode zum Aufrufen der Strategieklasse durch die Umgebungsklasse jedoch dieselbe ist, spiegelt dies Polymorphismus wider. Um unterschiedliche Algorithmen zu implementieren, müssen Sie lediglich die Strategieklasse in der Umgebungsklasse ersetzen.
In js müssen wir keine Strategieklasse erstellen, wir können Funktionen direkt als Strategieobjekte verwenden.
Beispiel
var strategies = { "s1": function() { //algo 1 }, "s2": function() { //algo 2 }, "s3": function() { //algo 3 } } var someContext = new SomeConext(); someContext.start("s1"); //using s1 to calculate //someContext.add("s1"); or add s1 as a rule for validation
kann auch als Fassadenmodus übersetzt werden. Es stellt eine konsistente Schnittstelle für eine Reihe von Schnittstellen in einem Subsystem bereit. Das Facade-Muster definiert eine High-Level-Schnittstelle, die die Verwendung dieses Subsystems erleichtert. Nachdem die Erscheinungsrolle eingeführt wurde, muss der Benutzer nur noch direkt mit der Erscheinungsrolle interagieren, und die komplexe Beziehung zwischen dem Benutzer und dem Subsystem wird durch die Erscheinungsrolle realisiert, wodurch die Kopplung des Systems verringert wird.
Wenn Sie beispielsweise zu Hause einen Film ansehen möchten, müssen Sie die Stereoanlage einschalten, dann den Projektor einschalten, dann den Player einschalten usw. Nachdem Sie die Erscheinungsfigur eingeführt haben, müssen Sie nur noch die aufrufen Methode „Filmgerät öffnen“. Die Darstellungsrolle umfasst Vorgänge wie das Öffnen des Projektors und bietet Benutzern eine benutzerfreundlichere Methode.
Komplexe Schnittstellen vereinfachen
Benutzer vom direkten Zugriff auf Subsysteme entkoppeln und schützen
Formal sieht der Darstellungsmodus in Javascript so aus:
function a(x){ // do something } function b(y){ // do something } function ab( x, y ){ a(x); b(y); }
Ein Beispiel unten, um Blasenbildung und Standardeinstellungen zu verhindern. Das Ereignis wird in die Darstellungsrolle eingefügt :
var N = window.N || {}; N.tools = { stopPropagation : function( e ){ if( e.stopPropagation ){ e.stopPropagation(); }else{ e.cancelBubble = true; } }, preventDefault : function( e ){ if( e.preventDefault ){ e.preventDefault(); }else{ e.returnValue = false; } }, stopEvent : function( e ){ N.tools.stopPropagation( e ); N.tools.preventDefault( e ); }
Die Anwendung des Darstellungsmodus in JavaScript kann hauptsächlich in zwei Kategorien unterteilt werden. Beispielsweise erscheint der Aufruf von Funktion a grundsätzlich wiederholt vor dem Aufruf von Funktion b. Dann können Sie diesen Code mit Darstellungsrollen umschließen, um die Struktur zu optimieren. Eine andere Möglichkeit besteht darin, APIs, die mit einigen Browsern nicht kompatibel sind, zur Beurteilung in das Erscheinungsbild zu integrieren. Der beste Weg, diese Probleme zu lösen, besteht darin, alle browserübergreifenden Unterschiede in einer Instanz des Erscheinungsbilds zu zentralisieren, um eine externe Schnittstelle bereitzustellen.
Definition des Proxy-Musters: Stellen Sie einen Proxy für andere Objekte bereit, um den Zugriff auf dieses Objekt zu steuern. In einigen Fällen ist ein Objekt nicht geeignet oder kann nicht direkt auf ein anderes Objekt verweisen, und ein Proxy-Objekt kann als Vermittler zwischen dem Client und dem Zielobjekt fungieren.
Virtueller Proxy verzögert die Erstellung und Ausführung einiger teurer Objekte, bis sie wirklich benötigt werden
//图片加载 let imageEle = (function(){ let node = document.createElement('img'); document.body.appendChild(node); return { setSrc:function(src){ node.src = src; } } })(); //代理对象 let proxy = (function(){ let img = new Image(); img.onload = function(){ imageEle.setSrc(this.src); }; return { setSrc:function(src){ img.src = src; imageEle.setSrc('loading.gif'); } } })(); proxy.setSrc('example.png');
Wenn es eine Funktion gibt, die häufige Anforderungsvorgänge erfordert, was relativ teuer ist, können Sie die Anforderungsdaten über einen bestimmten Zeitraum über eine Proxy-Funktion sammeln und sofort versenden
//上传请求 let upload = function(ids){ $.ajax({ data: { id:ids } }) } //代理合并请求 let proxy = (function(){ let cache = [], timer = null; return function(id){ cache[cache.length] = id; if(timer) return false; timer = setTimeout(function(){ upload(cache.join(',')); clearTimeout(timer); timer = null; cache = []; },2000); } })(); // 绑定点击事件 let checkbox = document.getElementsByTagName( "input" ); for(var i= 0, c; c = checkbox[i++];){ c.onclick = function(){ if(this.checked === true){ proxy(this.id); } } }
Cache-Proxy kann temporären Speicher für einige teure Operationsergebnisse bereitstellen. Wenn die übergebenen Parameter bei der nächsten Operation mit den vorherigen übereinstimmen, können die zuvor gespeicherten Operationsergebnisse direkt zurückgegeben werden
//计算乘积 let mult = function(){ let result = 1; for(let i = 0,len = arguments.length;i < len;i++){ result*= arguments[i]; } return result; } //缓存代理 let proxy = (function(){ let cache = {}; reutrn function(){ let args = Array.prototype.join.call(arguments,','); if(args in cache){ return cache[args]; } return cache[args] = mult.apply(this,arguments); } })();
1. Vorteile: Der Proxy-Modus kann das Proxy-Objekt vom aufgerufenen Objekt trennen, wodurch die Kopplung des Systems verringert wird. Der Proxy-Modus spielt eine Vermittlerrolle zwischen dem Client und dem Zielobjekt und kann das Zielobjekt schützen. Das Proxy-Objekt kann vor dem Aufruf des Zielobjekts auch andere Vorgänge ausführen.
2. Nachteile: Erhöht die Komplexität des Systems
Beobachtermodus
/** * 模块模式 = 封装大部分代码,只暴露必需接口 */ var Car = (function(){ var name = '法拉利'; function sayName(){ console.log( name ); } function getColor(name){ console.log( name ); } return { name: sayName, color: getColor } })(); Car.name(); Car.color('红色');
Verwandte Empfehlungen:
Detaillierte Erläuterung des js-Kombinationsentwurfsmusters
Detaillierte Erläuterung des Service-Locator-Musters, Beispiel eines PHP-Entwurfsmusters
Detaillierte Erläuterung des Delegationsmusters eines PHP-Entwurfsmusters
Das obige ist der detaillierte Inhalt vonGängige Entwurfsmuster in JS. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!