Sviluppo organico


introduzione

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.


Il concetto

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.


Scarica organico

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.


L'esempio

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!


DNA

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

Un Organel di base

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


Il router

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.


Provider di stili CSS

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.


Il rendering

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

Esecuzione dell'applicazione

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.


Conclusione

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.