Heim >Web-Frontend >js-Tutorial >Gängige Entwurfsmuster in JS

Gängige Entwurfsmuster in JS

小云云
小云云Original
2018-02-23 15:14:221492Durchsuche

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.

Singleton-Muster

Der Kern des Singleton-Musters besteht darin, sicherzustellen, dass es nur eine Instanz gibt und globalen Zugriff bereitzustellen.

Funktionen

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

Bewerbung

Das Anmeldefenster öffnet sich.

Instanz

 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";
}

Konstruktormodus

/**
 * 构造一个动物的函数 
 */
function Animal(name, color){
    this.name = name;
    this.color = color;
    this.getName = function(){
        return this.name;
    }
}
// 实例一个对象
var cat = new Animal('猫', '白色');
console.log( cat.getName() );

Prototypmodus

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

Gemischter Modus

/**
 * 混合模式 = 原型模式 + 构造函数模式
 */
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 )

Fabrik Muster

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();

Einfaches Fabrikmuster

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();

Iteratormuster

Dekorationsmuster

Strategiemuster

Definieren Sie gegenseitig austauschbare Algorithmen und kapseln Sie sie ein.

Funktionen

  1. 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;

  2. Trennen Sie die Implementierung und Verwendung des Algorithmus, um die Wiederverwendbarkeit des Algorithmus zu verbessern;

  3. Vermeiden Sie mehrere bedingte Auswahlanweisungen durch Kombination, Delegation und Polymorphismus.

Wenden Sie

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

Darstellungsmodus

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.

Funktion

  1. Komplexe Schnittstellen vereinfachen

  2. Benutzer vom direkten Zugriff auf Subsysteme entkoppeln und schützen

Beispiel

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.

Proxy-Muster

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

Virtueller Proxy verzögert die Erstellung und Ausführung einiger teurer Objekte, bis sie wirklich benötigt werden

Verzögertes Laden von Bildern

//图片加载
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');

Zusammenführen http-Anfragen

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

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);
    }
})();

Vorteile und Nachteile

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

Modulmodus

/**
 * 模块模式 = 封装大部分代码,只暴露必需接口
 */
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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn