L'organizzazione può creare o distruggere la manutenibilità di un'applicazione. Con le applicazioni più piccole, l'organizzazione è più evidente; tuttavia, con l'aumentare dell'applicazione e con l'aumento del numero di sviluppatori di applicazioni e ingegneri front-end che generano codice, l'organizzazione più confusa può diventare. In questo post, esamineremo alcuni concetti di base per mantenere le applicazioni organizzate in modo che la ricerca di codice rilevante sia un processo efficiente e sistematico.
JavaScript deve essere esaminato in modo efficiente.
Prendiamo un momento e consideriamo il modo in cui i team Rails e Wordpress organizzano i loro progetti. È probabile che tu abbia probabilmente lavorato con uno o l'altro di questi. Entrambi i framework hanno una struttura predefinita predefinita.
Quando genera un'applicazione Rails, Rails gestisce gran parte delle esigenze organizzative primarie per te. Poiché è basato su MVC, l'impostazione predefinita di Rails include una cartella denominata "app", che contiene le cartelle model / view / controller. Fornisce inoltre "helper" e "mailer", le estensioni del controller che aiutano a colmare le lacune tra controller e modelli.
Rails genera anche alcuni altri elementi allo stesso livello della cartella "app", come configurazione, registrazione, database, temporanea / cache, test e altri pezzi. Ciò che è particolarmente interessante in questa discussione sono le app e le cartelle pubbliche. La cartella pubblica è dove vengono servite le risorse statiche, compresi i file HTML, CSS e JavaScript non dinamici.
Quando si lavora con Wordpress, la denominazione e la struttura sono molto meno ovvi.
... l'applicazione è costruita per gli utenti ...
Le convenzioni sono esposte tramite la documentazione. In particolare, gli sviluppatori probabilmente lavorano all'interno di un tema, situato nella directory wp-content / themes /. Questo tema ha una serie di file con nomi speciali, principalmente basati su viste. UN functions.php
il file funge da "controller" di sorta, in cui uno sviluppatore può inserire funzioni per separarle dalle viste. Tuttavia, i temi di Wordpress spesso infangano le acque tra la logica e la presentazione. Ad esempio, le query di database sono implicite dal nomefile, ma spesso vengono manipolate alterando la query prima di eseguire il ciclo dei risultati restituiti. Questa manipolazione non è astratta allo stesso modo di un controller (e, naturalmente, Wordpress non è affatto vicino a MVC, quindi non possiamo aspettarci questo tipo di organizzazione).
Entrambi questi framework sono estremamente popolari, e entrambi usano la propria strutturazione implicita. Richiedono assolutamente che gli sviluppatori comprendano il modo in cui il sistema funziona per essere efficiente. Nelle nostre applicazioni, dovremmo prendere in considerazione questo paradigma organizzativo e creare un approccio sistematico per strutturare le applicazioni. Questo è molto diverso per ogni singola applicazione.
I framework menzionati sopra non richiedono che gli sviluppatori definiscano la struttura; sono "pre-cablati" per funzionare in un modo specifico.
Un motivo importante per cui i framework robusti spesso astraggono queste configurazioni e forniscono strutture predefinite è così che le persone inizieranno a sviluppare uno standard di comunità basato sulla struttura predefinita.
Non ignorare gli standard quando organizzi la tua applicazione!
Se hai familiarità con Rails, puoi molto probabilmente guardare un repository Github e sapere se si tratta di un'app Rails solo dalla struttura della cartella-- Rails ha uno standard documentato.
Non ignorare gli standard quando organizzi la tua applicazione! È molto probabile che se stai organizzando un'applicazione a livello aziendale, hai a che fare con mini-applicazioni modulari, basate su servizi discreti. Ad esempio, potrebbe essere il caso di avere più applicazioni costruite con uno o più framework diversi, oppure possono essere rotolate a mano e lavorare in combinazione tra loro, esponendo API che forniscono hook per gli altri servizi. Ciascuna di queste applicazioni discrete probabilmente segue gli standard del framework su cui è stata costruita; questi standard esistono perché sono il modo in cui questo framework è stato progettato per funzionare. Se provi a cambiare questi standard in un'applicazione discreta, probabilmente finisci sprecare più tempo nella configurazione che effettivamente costruendo un'applicazione funzionante.
In pratica, ciò significa che le cose che vengono esposte da un servizio a un altro dovrebbero funzionare in modo uniforme, e le parti interne a un servizio dovrebbero funzionare nel modo migliore per quel particolare servizio, probabilmente guidato da qualsiasi framework o stack tecnologico su cui viene eseguito il servizio.
Ricorda, alla fine della giornata, l'applicazione è costruita per gli utenti e gli utenti non conoscono o apprezzano la separazione dei servizi discreti.
Comprendono invece l'applicazione e l'esperienza come un unico pezzo, e quell'unico beneficio trarrà principalmente dall'uniformità ai massimi livelli.
Quindi cosa deve essere uniforme?
man mano che l'applicazione cresce ... l'organizzazione più confusa può diventare.
I percorsi (strutture URL) sono uno dei fattori di definizione più importanti di come funziona un'applicazione web. È importante che i percorsi seguano una struttura uniforme. Ad esempio, quando si visualizza un "account utente" con un URL come / User / 5
dove 5
è l'ID intero della chiave primaria dell'utente, non si dovrebbe usare un plurale per un altro oggetto singolare, come ad esempio / Widgets / 16
. Invece dovrebbe essere / Widget di / 16
. Ciò non solo aiuta gli sviluppatori a essere coerenti, ma fornisce anche chiarezza e uniformità per gli utenti. Non importa ciò che si sceglie per la struttura del percorso, purché sia coerente a livello di utente.
Questo è estremamente importante per lo sviluppo interno ed è ancora più importante per lo sviluppo di prodotti / servizi software in cui l'API è esposta al pubblico. Se le tue chiamate API hanno caratteri di sottolineatura come separatori di parole, non utilizzare una chiave CamelCase o dash-separate nella tua API altrove. Se si utilizza la parola "contare" per significare "restituire questo numero di oggetti", non utilizzare qualcosa come "count_per_page" per indicare la stessa cosa altrove nella stessa API (o correlata). Questo è un design API sciatto. Sviluppare una sintassi standard e attenersi ad essa; si noti che questo è spesso curato da una progettazione del percorso ben eseguita nelle API REST.
A livello generale, quando si ha a che fare con "foo widgets" (oggetti o azioni arbitrari) all'interno dell'applicazione, assicurarsi di utilizzare la stessa terminologia su tutte le applicazioni. Ad esempio, mentre può essere una pratica comune in Rails usare la directory "pubblica", si ha il controllo su ciò che accade all'interno di esso.
Non utilizzare una cartella "js" per un framework e una cartella "scripts" per un altro framework.
Non chiamare modelli di dati "orange_items" in un framework e "OrangeItems" in un altro, a meno che il linguaggio o il framework non richiedano esplicitamente questo per un motivo funzionale. Anche in questo caso, assicurati che ci sia un sistema e una "grammatica" coerenti e assicurati che le differenze tra i servizi discreti siano ben documentato e giustificato. Questi tipi di segnali e uniformità aiuteranno notevolmente la comprensione delle classificazioni degli oggetti attraverso un'applicazione.
Il mirroring dei percorsi verso cartelle e file aiuta a mantenere organizzata un'applicazione. Ad esempio, potresti avere cartelle per CSS, JavaScript e immagini all'interno delle cartelle "pubbliche" o "statiche". La creazione di una struttura di cartelle che si associano ai percorsi, alle viste, ai controller o ad altre strutture simili può aiutare a mantenere il tuo CSS modulare. È quindi possibile utilizzare uno strumento come CodeKit per concatenare questi file in un singolo file minificato. Certo, potresti anche avere un global.css
per le regole che si applicano a tutta l'applicazione. Vedi sotto per un esempio (.rb è per Ruby, ma questo potrebbe andare per qualsiasi organizzazione framework di MVC).
- root / - app / --- models / ---- foo.rb ---- bar.rb ---- baz / ----- widget.rb --- views / ---- global. html.erb ---- foo.html.erb ---- bar.html.erb ---- baz / ----- widget.html.erb --- controller ---- foo.rb - - bar.rb - public - CSS --- global.css --- foo.css --- bar.css --- baz / ---- widget.css - JS --- global.js - - foo.js --- bar.js --- baz / ---- widget.js - Immagini / --- global / ---- image.jpeg --- foo ---- image.jpeg --- bar ---- image.jpeg --- baz / ---- widget / ----- image.jpeg
Si può vedere rapidamente che non sarebbe difficile trovare specifici CSS, JavaScript, modelli, ecc. Per una sezione specifica dell'applicazione.
I percorsi (strutture URL) sono uno dei fattori di definizione più importanti di come funziona un'applicazione web.
Il modo migliore per pensare a questo è quello di separare i file in "aree" del tuo sito. Ad esempio, forse hai un'applicazione che include un'area "admin" e un'area "profilo". Potresti creare un global.css
file per contenere gli oggetti / regole che si applicano ad entrambe le aree (incluso un reset, alcune regole tipografiche, colori, ecc.) e quindi creare file specifici che si applicano alle aree separate per le regole dello stile dei contenuti che non sono condivise. In questo modo, mentre uno sviluppatore lavora su una pagina specifica, rimarrà in uno o due file e saprà esattamente dove trovare i file giusti.
Un altro modo efficace per controllare i file statici è nominarli in base a ciò che fanno. Ad esempio, crea un reset.css
, un typography.css
, un dimensions.css
, un colors.css
, ecc. Ci sono pro e contro a questo metodo, in particolare per i CSS. Mantiene il tuo CSS focalizzato sulle regole di presentazione; tuttavia, sarà probabilmente necessario ripetere i selettori su più file, riaprendoli per definire diversi tipi di regole di stile. L'unico modo per evitarlo è nominare le tue classi / ID solo per stile piuttosto che per semantica, come ad esempio class = "green-text five-columns medium-shadow"
. Altrimenti, finirai per fare qualcosa del genere:
Nel typography.css
.semantic-widget color: # 232323; text-shadow: 1px 1px #fff; font-size: 1.2em; line-height: 1.1em; font-family: sans-serif; font-weight: 300;
Nel dimensions.css
.semantic-widget width: 20%; margine: 0 2,5%; imbottitura: 10px;
Quale naturalmente non è ASCIUTTO come possibile.
L'organizzazione di applicazioni più piccole (con meno di questi oggetti "widget") può ancora trarre vantaggio dalla separazione per tipo di regola.
Tuttavia, se hai un'applicazione con molti tipi di oggetti, aree applicative, ecc., Dovresti probabilmente scegliere di separare i tuoi file CSS in aree (la strategia di mirroring che abbiamo discusso sopra)..
La denominazione di file JavaScript in base alle loro funzioni è un po 'più fattibile, ma solo se si sta sfruttando i trigger di evento (un modello di pubblicazione / sub). Considera il seguente esempio:
$ .getJSON ("/ messages / all.json", function (data) // do some stuff);
Potresti voler fare un bel po 'di cose in questo callback. Potresti voler inviare una notifica all'utente e aggiornare un elenco di messaggi. Se i tuoi file sono separati da funzionalità, potresti avere un notifications.js
e a messages.js
file che gestiscono queste particolari funzioni. All'interno del callback per questa chiamata JSON ajax, si dovrebbe "pubblicare" un evento sul resto dell'applicazione. Quindi all'interno dei tuoi file di notifiche e messaggi, puoi "iscriverti" all'evento e rispondere di conseguenza.
nel events.js
:
$ .getJSON ("/ messages / all.json", function (messages) $ ("body"). trigger ("received_messages", messages););
nel messages.js
:
$ ("body"). on ("received_messages", function (event, messages) // itera attraverso i messaggi e accoda ad una lista);
nel notifications.js
$ ("body"). on ("received_messages", function (event, messages) // send_notification può essere una funzione locale che consente di inviare notifiche // all'utente, insieme a un tipo di notifica, un intero; Per esempio, in questo // caso, "1" può semplicemente significare come stile la notifica come un avviso "successo" send_notification ("Messaggi ricevuti con successo!", 1););
Ci sono alcune cose da tenere a mente sui tuoi file statici. In questo articolo si presuppone che concatenate i file statici in modo appropriato. Ma cosa è esattamente appropriato?
Quindi, perché dovresti farlo, chiedi? Principalmente per sfruttare la cache del browser.
La concatenazione al volo, ad esempio, non ti consente di sfruttare la cache del browser. L'altro vantaggio di questo approccio è caricare solo ciò di cui hai bisogno. Se hai un'intera sezione "admin" che il 95% dei tuoi utenti non vede, non dovrebbe scaricare il CSS per quella sezione.
Sviluppare una sintassi standard e attenersi ad essa.
Simile al CSS, JavaScript deve essere definito in modo efficiente.
I guadagni dovrebbero essere sempre gestiti con attenzione; se il tuo javascript è abbastanza piccolo da giustificare la concatenazione in un singolo script, a tutti i costi, non sentirti sotto pressione per caricare JavaScript modulare nel tuo prodotto finale.
Come accennato brevemente sopra, se c'è un numero trascurabile di utenti che colpisce una pagina specifica, non mettere il CSS / JS nei file statici dell'applicazione globale. Anche i file statici amministrativi dovrebbero rimanere separati. Se l'applicazione supporta gli account utente, prendere in considerazione la possibilità di escludere i file statici per il lato non autorizzato (marketing) dell'applicazione. Una volta che un utente effettua l'accesso, ha già preso l'impegno di prendere parte a qualsiasi richiesta dell'applicazione. Le prime impressioni sono tutto e il caricamento di una serie di CSS e JavaScript inutilizzati non farà che peggiorare le prestazioni di una prima impressione.
Se stai effettivamente usando un framework, usa la struttura esistente di quel framework. Se il tuo framework non ha una struttura esistente, o una struttura molto semplice (Sinatra e CodeIgniter sono ottimi esempi di questo), considera il mirroring della struttura di altri componenti nell'applicazione. Se stai iniziando da zero, dai un'occhiata ad altri progetti che le persone hanno completato sia nel framework che stai utilizzando sia in altri framework che usano la stessa lingua. Ad esempio, se il framework scelto funziona su MVC ma non ha configurazioni predefinite per il posizionamento di questi pezzi, è probabile che ci sia un nome convenzione che utilizza le parole chiave Model, View e Controller.
Quando si tratta di esso, l'organizzazione a livello aziendale è composta da quattro cose principali: