2013-04-16 20 views
7

In questi discorsi di Nicholas Zakas e Addy Osmani discutono l'idea di utilizzare il modello di facciata come sandbox quando si creano applicazioni Javascript su larga scala, al fine di separare l'applicazione dalle librerie di base sottostanti.Estratto di jQuery

Questo disaccoppiamento consentirebbe in teoria di cambiare una libreria di base senza dover riscrivere i moduli dell'applicazione. Tuttavia nella pratica questo sembra essere più difficile da attuare.

Esistono implementazioni concrete di questa architettura proposta, ad esempio AuraJS. Comunque guardando la fonte sembra che la sandbox abbia ancora delle astrazioni che perdono restituendo oggetti jQuery da alcuni dei suoi metodi.

Non mi interessa specificamente AuraJS, ma più il concetto generale di cercare di astrarre una libreria come jQuery senza perdere così tanta funzionalità.

Ad esempio, la mia facciata/sandbox ha un metodo dom .find(selector). Mi vengono in mente 3 opzioni per quello che potrebbe restituire:

  1. Un oggetto jQuery - Questo sarebbe fuoriuscire jQuery fuori nei moduli che consumano.

  2. Un elemento dom grezzo - Perdita di funzionalità, nessuno vuole davvero lavorare con questo! Nessuna catena.

  3. Un wrapper personalizzato jQuery-like - Potrebbe essere piuttosto complesso, ma sembra la soluzione ideale.

Quindi la mia domanda è, come è possibile astratto una libreria come jQuery senza perdere troppo funzionalità, tale da poter essere sostituito ad un certo punto in futuro, con il minimo sforzo?

+0

jQuery è abbastanza complicato internamente, creando un'astrazione tale da poter essere sostituito da qualsiasi (o anche da una) altra libreria sembra estremamente difficile. E qual è il punto? Se pensi che potresti voler scambiare le librerie in futuro, forse non dovresti usare quello che stai usando in primo luogo. – RobG

+0

@RobG Sono d'accordo sembra difficile, ed è per questo che sto facendo la domanda. Per quanto le persone di gran lunga più intelligenti di me stiano facendo queste proposte e fornendo loro validi motivi (vedi i link ai discorsi forniti). –

+0

Nell'architettura di Nicholas, se cambi la libreria di base, dovresti anche riscrivere il core dell'applicazione. Una volta superato il nucleo, non si sta più scrivendo il codice che utilizza la libreria. Se stai usando jQuery, la persona che scrive un modulo non scrive ** nessun ** jQuery. – RobG

risposta

0

Penso che tu stia chiedendo di scrivere un codice più modulare, ma jquery non è un buon caso.

asincrono del modulo Definizione http://addyosmani.com/writing-modular-js/

+0

Si prega di consultare i collegamenti ai colloqui che ho fornito. Questo è più che semplicemente scrivere codice modulare. –

0

Ecco un esempio molto semplice di utilizzare moduli come un'architettura:

<!DOCTYPE html> 
<title>Module play</title> 
<body> 
<script> 

// myCore provides all functionality required by modules 
// Could use a library in here 
var myCore = { 

    getContainer: function() { 
    // code in here to find a suitable container in which to put widgets 
    // This is where different client capabilities will be tested to ensure the 
    // widget behaves in it's user agent context - desktop, phone, tablet, pad, etc. 

    // very simple shortcut 
    return { 
      element: document.body, 

      // This function could use a general purpose library 
      add: function(widget) { 
       this.element.appendChild(widget.getElement()); 
      } 
    }; 

    }, 

    // This function could use a general purpose library 
    getNewWidget: function() { 
    var element = document.createElement('div'); 

    return { 

     getElement: function() { 
     return element; 
     }, 

     display: function(text) { 

     // Tightly couple to itself or not? 
     this.getElement().innerHTML = '<em>' + text + '</em>'; 

     // or 
     element.innerHTML = '<em>' + text + '</em>'; 
     } 
    } 
    } 
}; 

// Missing sandbox layer... 

// Add a module - only uses myCore API (access should be controlled by 
// the sandbox), does not deal with underlying library or host objects 
(function() { 

    // Get a container to add a widget too 
    var container = myCore.getContainer(); 

    // Create a widget 
    var widget = myCore.getNewWidget(); 

    // Add the widget to the container 
    container.add(widget); 

    // Give something to the widget to display 
    widget.display('Hello World'); 

}()); 

</script> 
</body> 

Così si può vedere che a livello di modulo, non si preoccupano l'host ambiente o libreria sottostante, si sta semplicemente scrivendo ECMAScript semplice. È possibile ottenere davvero sulla difensiva e fare cose del tipo:

(function() { 
    var container, widget; 

    if (!myCore) return; 

    if (myCore.getContainer) { // Some would include an isCallable test too 

     container = myCore.getContainer(); 
    } 

    // getWidget could be a method of container instead so that 
    // everything you need is either a method or property of container 
    // or widget 
    if (myCore.getWidget) { 
     widget = myCore.getWidget(); 
    } 

    ... 
} 

e così via quindi tutto è testato e controllato. Ho omesso la gestione degli errori, ma spero che l'esempio sia sufficiente.

+0

Grazie per questa risposta dettagliata, vedo da dove vieni. Tuttavia sembra che tu stia essenzialmente spingendo verso il basso la funzionalità e il comportamento del widget, lasciando i moduli reali come consumatori stupidi. Penso che sia troppo restrittivo e non penso che sarebbe scalabile per un'applicazione enterprise. La mia comprensione è che il core dovrebbe fornire insiemi di ** funzionalità ** (ad esempio dom manipulation/ajax/mediator) che nascondono le implementazioni della libreria di base e vengono quindi esposte attraverso una sandbox che funge da livello "colla" coerente tra i moduli e il centro. –

+0

Vedi le diapositive 40/51/66 del discorso di Nicholas. Non c'è nulla da suggerire che i moduli non possano controllare la dom nel loro ambito. Per fare ciò è necessaria una certa forma di "servizio" di manipolazione dom dal core/sandbox. Vedi le diapositive 105-109 del discorso di Addy per un esempio di ciò che intendo. Essenzialmente la sandbox dovrebbe fornire una serie di "servizi" ai moduli. Sono i valori di ritorno (se presenti) di quelle chiamate di servizio che trovo difficili da astrarre. –

+0

Controlla anche la fonte di [AuraJS] (https://github.com/aurajs/aura/tree/master/lib) (implementazione di Addy dell'architettura di Nicholas). Vedrai come vengono create le sandbox da base.js e quelle che vedo come le astrazioni che perdono in ciò che viene restituito dai metodi sandbox (principalmente oggetti jQuery). Grazie per il tuo tempo! –