Qualche anno fa lavoravo come graphic designer e un problema comune che avrei incontrato era la scelta di combinazioni di colori per i nuovi progetti. Uno dei miei colleghi ha detto, "Scegli una bella foto e prendi i colori da lì". Questa tecnica funziona bene perché le foto ti offrono una combinazione naturale di colori. Quindi stavo pensando, "Perché non trasferire questo stesso concetto al mio lavoro di programmatore?". Ed è qui che entra in gioco Organic. Quando sono stato introdotto per la prima volta all'organico mi sono stupito di quanto fosse semplice e, al tempo stesso, quanto sia flessibile il suo approccio. Infine, ho avuto qualcosa che incoraggia la programmazione modulare, è tanto utile quanto il pattern MVC, ed è un ottimo strumento per l'architettura.
Come avrai intuito, il concetto organico è basato sulla biologia. La tua applicazione principale funge da Cellula, che ha un Membrana e a Nucleo. Ma il vero lavoro di una cellula è fatto dal organelli, che comunicano tra loro con Sostanze chimiche. Ovviamente, gli elementi e i processi in Organic non sono identici al 100% alle celle di vita reale, ma sono piuttosto vicini. Ora, so che sembra pazzesco, ma una volta che inizierai a lavorare con esso vedrai quanto semplice e naturale possa essere questo approccio quando lo applichi alle tue app.
Organic è distribuito come un modulo Node. Quindi dovresti avere già installato NodeJS. Se non lo fai, vai su nodejs.org e prendi l'ultima versione per il tuo sistema operativo. Il tuo package.json
il file dovrebbe assomigliare a questo:
"nome": "OrganicDevelopment", "versione": "0.0.0", "descrizione": "Sviluppo organico", "dipendenze": "organico": "0.0.11", "autore": "Il tuo Nome qui "
Correre installazione di npm
nella stessa directory e il manager scaricherà i file necessari. Il nucleo di Organic è in realtà piuttosto piccolo. Contiene solo la definizione degli elementi principali: Cellula, Nucleo, Membrana, Plasma, Organella, Chimica e DNA. Ovviamente viene fornito con alcuni test, ma nel complesso è un piccolo pacchetto. Ciò aiuta a rendere più facile l'apprendimento e lo sviluppo con quasi immediatamente.
Per questo articolo ho deciso di creare un semplice sito web utilizzando solo il nucleo di organico. Il codice sorgente può essere scaricato nella parte superiore di questo articolo, se desideri seguirlo. Penso che questa applicazione di esempio sia il modo migliore per presentare questo nuovo modello. Il sito contiene due pagine - Casa
e Di
. Ecco uno screenshot del sito:
L'app contiene due pulsanti che collegano le due diverse pagine. Il Di
pagina ha solo un po 'più di testo rispetto al Casa
la pagina lo fa. Abbastanza semplice, ma vediamo cosa c'è dietro le tende. Ecco un diagramma che mostra il flusso di richieste di base della nostra applicazione:
L'utente invia una richiesta alla nostra applicazione NodeJs. Il server accetta la richiesta e la invia al router. Successivamente, il rendering sa quale pagina deve essere utilizzata e restituisce una risposta al server. Alla fine, la risposta viene quindi inviata all'utente.
C'è un elemento aggiuntivo, i fornitori di dati, che prepara il necessario CSS o JavaScript per il rendering (tieni presente che nella nostra app di esempio non ho usato JavaScript, c'è solo un modulo CSS).
Ecco come apparirà la nostra app come cella, in Organic:
Nella cella, abbiamo una membrana che mantiene gli elementi interni lontano dal mondo esterno. All'interno di questa membrana è dove metteremo il nostro primo organello, il nostro Server, perché è qui che i dati possono entrare o uscire dalla nostra applicazione. Gli altri organelli (Router, Render e CSS) sono posizionati nel plasma. Tutti questi moduli comunicano tra loro tramite sostanze chimiche (richiesta, pagina e css, segnato in rosso). Il server emette a richiesta chimica. Il router emette a pagina e l'organel CSS invia il css. Vorrei anche ricordare che il plasma funge da bus per eventi per i prodotti chimici. Organelles ascolta una sostanza chimica particolare e, se trovata, reagisce.
Ecco un altro diagramma di flusso delle richieste, ma questa volta con i prodotti chimici emessi (contrassegnati in rosso):
Ora, se questo concetto non ti è ancora chiaro, non ti preoccupare, mentre procediamo attraverso le prossime sezioni e prendiamo il codice attuale, dovrebbe cominciare a dare più senso!
Tutto inizia con il DNA (acido desossiribonucleico), che puoi pensare come configurazione di una cella. Questo DNA è dove definirai i tuoi organelli e le loro impostazioni.
Creiamo un nuovo index.js
file e inserire il seguente codice:
var DNA = require ("organic"). DNA; var Cell = require ("organic"). Cell; var dna = nuovo DNA (membrana: Server: fonte: "membrana.Server", plasma: Router: fonte: "plasma.Router", CSS: fonte: "plasma.CSS", file : "./css/styles.css", Render: source: "plasma.Render", templates: "./tpl/"); var cell = new Cell (dna);
Il codice precedente è solo una definizione per l'inizializzazione di DNA e cella. Potete vedere che abbiamo inserito il nostro Server nella membrana e il Router, CSS e Render nel plasma, come abbiamo discusso nell'ultima sezione. Il fonte
la proprietà è in realtà obbligatoria e contiene il percorso per i singoli organelli.
Tieni presente che il file
proprietà nel CSS organel e il modelli
le proprietà nel rendering organel sono in realtà proprietà personalizzate, che ho impostato. Puoi aggiungere qualsiasi personalizzazione di cui hai bisogno anche qui.
E solo per riferimento, la struttura della directory per la tua app dovrebbe apparire così:
/ css /styles.css / membrane /Server.js / node_modules / plasma /CSS.js /Render.js /Router.js / tpl
var Chemical = require ("organic"). var Organel = require ("organic"). Organel; var util = require ("util"); module.exports = function YourOrganelName (plasma, config) Organel.call (this, plasma); // la tua logica personalizzata qui util.inherits (module.exports, Organel);
Il codice sopra mostra il formato base per la creazione di un organo. Se vuoi usarlo this.emit
o this.on
dovrai assicurarti di ereditare Organel come abbiamo fatto sopra. E in realtà, il plasma
la variabile parametro ha quegli stessi identici metodi (emettere
e sopra
), quindi puoi usare plasma
direttamente e saltare l'ereditarietà se lo si desidera.
Inoltre, nota il config
parametro; Questo è l'oggetto che hai definito nel tuo DNA, che è un buon posto per qualsiasi tua configurazione personalizzata.
Il server è il tuo organello principale, che accetta richieste e invia risposte al browser. Ecco come dovrebbe apparire il tuo Server Organel:
var port = 3000; module.exports = function Server (plasma, config) Organel.call (this, plasma); var auto = questo; http.createServer (function (req, res) console.log ("request" + req.url); self.emit (new Chemical (tipo: "richiesta", req: req), function (html) res .writeHead (200); res.end (html););). listen (porta, '127.0.0.1'); console.log ('Server in esecuzione su http://127.0.0.1:' + porta + '/');
Qui stanno succedendo due cose. La prima è la definizione del server NodeJS, che ovviamente ha una richiesta di accettazione del gestore (req
) e risposta (res
) oggetti. Una volta ricevuta la richiesta, il Server Organel invia una sostanza chimica, con il tipo richiesta
, notifica al resto degli organelli. Si allega anche il req
oggetto, quindi chiunque abbia bisogno di maggiori informazioni sulla richiesta in arrivo può accedere direttamente ai dati dalla sostanza chimica.
Il emettere
il metodo prende quindi un secondo argomento che è una funzione di callback. Puoi usare questo per riportare il flusso all'organo, che invia la sostanza chimica. Cioè una volta che il rendering termina il suo lavoro, chiama il callback del server. Prende l'HTML prodotto e usando il res
oggetto invia la pagina all'utente.
Per il nostro prossimo organel, il Router ascolta solo per richiesta
chimica, che viene inviata dal server. Ottiene l'URL dal req
oggetto e decide quale pagina deve essere mostrata. Ecco il codice per il router:
module.exports = function Router (plasma, config) Organel.call (this, plasma); var auto = questo; this.on ("richiesta", funzione (chimica, mittente, callback) var page = chemical.req.url.substr (1, chemical.req.url.length); page = page == "" || page = = "/"? "home": page; self.emit (new Chemical (type: "page", page: page, ready: callback)););
Ora, il router stesso emette solo una nuova sostanza chimica con un tipo di pagina
. Tieni presente che ci sono altri due organelli che ascoltano anche questa sostanza chimica, ma per impostazione predefinita non vengono trasferiti a tutti gli altri elementi nel plasma. Naturalmente, ci possono essere momenti in cui avrete bisogno di tale funzionalità. Per fare ciò, devi solo restituisce falso;
nell'ascoltatore della chimica. Vedremo questo in azione nella prossima sezione.
module.exports = function CSS (plasma, config) Organel.call (this, plasma); var cssStyles = fs.readFileSync (config.file) .toString (); var auto = questo; this.on ("page", function (chemical) self.emit (new Chemical (type: "css", value: cssStyles)); return false;);
Questo modulo è solo un semplice organello di un compito che ottiene il percorso verso il .css
file, lo legge e successivamente emette una sostanza chimica contenente gli attuali stili CSS. Inoltre, prestare attenzione al restituisce falso;
affermazione in fondo. Come ho detto dall'ultima sezione, è importante farlo, altrimenti il Render non riceverà il pagina
prodotto chimico inviato dal router. Questo accade perché l'organel CSS è definito prima del Render nel DNA.
E infine, ecco il codice per il nostro organo di rendering:
module.exports = function Render (plasma, config) Organel.call (this, plasma); var getTemplate = function (file, callback) return fs.readFileSync (config.templates + file); var formatTemplate = function (html, templateVars) for (nome var in templateVars) html = html.replace ("" + name + "", templateVars [nome]); return html; var templates = layout: getTemplate ("layout.html"). toString (), home: getTemplate ("home.html"). toString (), about: getTemplate ("about.html"). toString (), notFound: getTemplate ("notFound.html"). toString () var vars = ; var auto = questo; this.on ("css", function (chemical) vars.css = chemical.value;); this.on ("page", function (chemical) console.log ("Opening" + chemical.page + "page."); var html = templates [chemical.page]? templates [chemical.page]: templates. notFound; html = formatTemplate (templates.layout, content: html); html = formatTemplate (html, vars); chemical.ready (html););
Esistono due metodi di supporto qui: getTemplate
e FormatTemplate
che implementano un semplice motore di template per caricare un file HTML esterno e sostituire le variabili in stile baffi. Tutti i modelli sono archiviati in un oggetto per un accesso rapido. In seguito abbiamo solo poche righe per la formattazione HTML e quindi tutto è pronto per partire. Anche il rendering organel ascolta il css
chimica e infine l'applicazione fornisce a non trovato
404 pagine, se necessario.
Ecco come appare la struttura della directory dell'app finale:
/ css /styles.css / membrane /Server.js / node_modules / plasma /CSS.js /Render.js /Router.js / tpl /about.html /home.html /layout.html /notFound.html
Semplicemente corri nodo index.js
nella console e dovresti vedere qualcosa di simile a questo:
Con il tuo server in esecuzione, dovresti essere in grado di visitare http://127.0.0.1:3000
nel tuo browser preferito. Prova a fare clic sui collegamenti per alternare tra le due pagine alcune volte e quindi tornare alla console per visualizzare l'output.
Dovresti vedere una bella relazione sull'attività recente delle applicazioni. Ora puoi anche notare qualcos'altro nella console:
richiesta /favicon.ico Apertura della pagina favicon.ico.
Puoi vedere che c'è un'altra richiesta proveniente dal browser. Vuole caricare favicon.ico
. Tuttavia il nostro piccolo sito non ha una tale icona, quindi apre solo la pagina 404. Puoi provarlo tu stesso visitando: http://127.0.0.1:3000/favicon.ico
.
Se desideri verificare il codice sorgente completo per questo tutorial, puoi scaricarlo utilizzando il link di download nella parte superiore di questa pagina.
Secondo me, Organic è un grande concetto. È molto flessibile e incoraggia a produrre applicazioni migliori. Tieni presente che l'esempio in questo articolo si basa sulla mia esperienza personale con altri modelli di progettazione. Quindi il mio uso di termini come Router, Data Provider o Render è completamente opzionale e puoi cambiare i nomi come meglio credi. Sentiti libero di sperimentare creando nuovi moduli basati su Organic e fammi sapere cosa ne pensi nei commenti!
Il nucleo di Organic è sviluppato da Boris Filipov e Valeri Bogdanov e consiglio vivamente di dare un'occhiata a Github. Se sei interessato all'utilizzo di Organic, troverai cose come Angel e WebCell davvero utili.