Contratti il lato pratico della semantica

Riconosciamo tutti che dovremmo scrivere codice semantico. Forse, stai anche usando

o correttamente, e si sentono abbastanza bene con te stesso. Ma stai considerando anche il contratto implicito che esiste quando codifichi?

Immaginiamo che un cliente richieda un link testuale, "Vedi altro,"Che dovrebbe rivelare un testo aggiuntivo sulla pagina. Vedi altro con un click handler dovrebbe funzionare perfettamente, giusto? Ehi, sembra e funziona come richiesto!

No, non funzionerà sempre correttamente, in quanto viola il contratto tra te e il browser. In particolare, mi riferisco a quello che dice il href l'attributo deve avere un valore che è un URL valido.

Ci sono problemi pratici che possono sorgere quando si violano i contratti, e quelli sono ragioni molto migliori per scrivere il codice semantico di quanto si pensi abitualmente quando si sente il termine "semantico".


Argomenti popolari per il codice semantico

Ci sono, tuttavia, ragioni molto più pratiche per preoccuparsi della semantica: i contratti.

Se chiedi a uno sviluppatore medio quale sia il valore del codice semantico, probabilmente ascolterai qualcosa sulla falsariga di:

  • Aiuta i disabili
  • La corretta descrizione del codice facilita l'interpretazione delle macchine

Entrambi sono, sfortunatamente, molto facili da trascurare. "I non vedenti ei robot non sono il pubblico di destinazione" è una risposta troppo semplice, indipendentemente da quanto erronea o ignorante possa essere.

In altri casi, potresti persino sentire un ragionamento ciclico, come "il codice non semantico è cattivo, perché non è significativo". È una nozione così popolare al punto che parodie su di esso sono già sorti sul web!

Ci sono, tuttavia, ragioni molto più pratiche per preoccuparsi della semantica: i contratti.


Contratti d'uso

Ogni volta che usi alcune funzionalità fornite dai venditori di browser, dal tuo linguaggio di programmazione o da un'API, stai facendo affidamento su un contratto.

Su un lato del contratto esiste un fornitore di funzionalità. Ad esempio, quando usi un tag, gli sviluppatori di browser ti promettono che forniranno un modo semplice per l'utente della tua applicazione di navigare verso l'URL specificato.

Come sempre, tuttavia, c'è l'altra faccia di quel contratto. L'implementatore della funzionalità promette di utilizzare la funzionalità come specificato. Non appena abusa di questa funzionalità, tutte le scommesse vengono interrotte, portando a un potenziale fallimento.

Contratti di funzionalità del browser

Torniamo al "Vedi altro"Esempio di prima. Agli inizi di JavaScript, gli sviluppatori scrivevano il loro JavaScript usando uno pseudo protocollo, javascript:

 Vedi altro

Relativamente rapidamente, hanno iniziato a rendersi conto che questo approccio ha almeno un difetto pratico: il codice JavaScript viene visualizzato nella barra di stato del browser, che non sembra professionale. La risposta a questo dilemma era spostare il codice in un al clic gestore e sostituire il href attributo con un identificatore di hash vuoto, in questo modo:

 Vedi altro

Certo, questo non ha risolto tutto. Se Mostra di più ha un errore, restituisce falso non viene mai chiamato e la pagina viene spostata verso l'alto - comportamento certamente non desiderato.

Oggi gli sviluppatori separano il loro codice HTML e JavaScript e utilizzano tecniche appropriate di prevenzione degli eventi:

 Vedi altro
 $ ('a.show-more'). on ('click', function (event) event.preventDefault (); ShowMore (););

Ma indovina un po? Ci sono ancora molti problemi con questo approccio: aprire una nuova scheda, aggiungere un segnalibro o copiare il collegamento non funziona come ci si potrebbe aspettare (in particolare, se c'è un tag sulla pagina), che si traduce in confusione e, possibilmente, in un cliente perduto.

Si noti come tutti i problemi descritti finora derivino da un singolo fatto. Gli sviluppatori hanno violato la loro parte del contratto con i produttori di browser: href l'attributo deve contenere un URL corretto, ma, invece, gli sviluppatori stavano inserendo tutti i tipi di garbage.

Se proviamo a conformarci al nostro contratto, dobbiamo chiederci: "Perché il contratto non ci consente di fare ciò di cui abbiamo bisogno?" La risposta è semplice: abusiamo del etichetta. Lo usiamo solo perché vogliamo il testo "Vedi altro"Apparire e comportarsi come un collegamento. Tuttavia, quando usiamo le parole, come "guarda" e "appare", non è questo il dominio dei CSS? Non è questo?Vedi altro"link, in realtà, solo un pulsante? Questo è facile da implementare:

 
 $ ('button.show-more'). on ('click', ShowMore);
 a, .link-style color: @ your-shade-of-blue; decorazione del testo: sottolineatura;  .link-style font: inherit; sfondo: nessuno; confine: nessuno; cursore: puntatore; 

Indipendentemente dal numero di nuovi modi per interagire con i collegamenti vengono aggiunti alle future iterazioni dei browser, questo approccio continuerà a funzionare, perché non stiamo violando alcun contratto con il browser. Utilizziamo elementi per comunicare il loro significato e, invece di lavorare costantemente intorno a nuovi problemi, sappiamo che il browser lo tratterà correttamente, poiché capisce ciò che vogliamo.

Certo, potrebbe richiedere qualche riga in più di CSS per ripristinare alcuni stili di pulsanti predefiniti. Ne vale la pena! Non essere pigro.

Specifiche come contratti

... quelli che conoscevano la semantica e li ignorarono consapevolmente.

Nel 2005, una grande parte della comunità di sviluppo Web ha imparato a fondo che ignorare i requisiti HTTP è sbagliato. Google Web Accelerator, rilasciato di recente, prefigura gli URL su una pagina per ridurre al minimo il tempo di attesa dell'utente con un clic.

Questo ha distrutto il disastro nelle applicazioni, che ha ignorato l'HTTP e ha messo in atto operazioni distruttive dietro semplici collegamenti. E c'erano molte di queste applicazioni.

Il problema non era nelle mani degli sviluppatori che non capivano la semantica dei metodi HTTP. No, il problema proveniva da coloro che conoscevano la semantica, ignorandoli consapevolmente e non condividendo la conoscenza.


Contratti di manutenzione

Il codice confuso è cattivo!

Esistono anche contratti tra gli sviluppatori. Ogni volta che scrivi una riga di codice, prometti ai futuri sviluppatori che fa esattamente ciò che sembra fare. In altre parole, il codice confuso è cattivo!

Ad esempio, utilizzando una funzione di filtro (come filtro in Python) per eseguire il loop sugli elementi non è corretto, poiché esiste un contratto implicito che le funzioni di filtro modificano solo l'elenco senza effetti collaterali:

 def show (item): print (item) fruits = ['orange', 'apple', 'lemon'] filter (mostra, frutta) # Uso errato del filtro

Invece, usa il ciclo esplicito su un elenco:

 def show (item): print (item) fruits = ['orange', 'apple', 'lemon'] per frutta in frutta: spettacolo (frutta)

D'altra parte, se puoi contare su un contratto, di conseguenza, ti consente di chiarire il tuo codice. Ad esempio, utilizzando array_filter invece di a per loop in PHP per filtrare gli elementi consente agli altri sviluppatori di capire cosa sta succedendo dopo un singolo colpo d'occhio:

 $ redditi = [20, 15, -7, 19]; $ profits = array_filter ($ reddito, funzione ($ i) return $ i> 0;);

Confronta lo snippet sopra con l'uso di a per ciclo continuo:

 $ redditi = [20, 15, -7, 19]; $ profitti = []; foreach ($ guadagna come $ i) if ($ i> 0) $ profit [] = $ i; 

La seconda versione è peggiore, non solo perché è più lunga, ma anche perché array_filter fornisce un'aspettativa. È chiaro che $ profitti è un sottoinsieme di $ redditi. Non esiste una tale convenzione con un generico per loop, che spiega il motivo per cui non possiamo formulare ipotesi, senza prima decifrare le parti interne del ciclo.


Scrivere correttamente codice semantico

Come fai a distinguere tra codice che è e non è semantico? Come noti questi contratti? Per la maggior parte, è sufficiente porsi delle domande.

Tag HTML

"Sto usando un tag e ho bisogno di mettere qualcosa in un href attributo. href memorizza la destinazione del collegamento. Allora, dove è il mio tag link to? "Da nessuna parte? Bene, posso quindi concludere che sto probabilmente abusando di questo tag.

Funzioni nominate

"Ho bisogno di stampare il contenuto della mia lista in a filtro funzione. La stampa degli articoli fa parte del processo di filtraggio? "Non proprio. Ciò significa che sto abusando filtro.

Funzioni che fanno troppo

"Sto scrivendo a getFoo metodo e necessario aggiungere un codice di modifica al suo interno. Lo stato di modifica ha senso come parte dell'ottenere pippo? Chiunque vorrebbe semplicemente ottenere si aspetta che succeda qualcos'altro? "Probabilmente no!

Separazione degli interessi

"Voglio aggiungere qualche JavaScript all'interno di un HTML al clic attributo. È corretto? "Il file che stai modificando è .html, destra? Invece, inserisci JavaScript e CSS all'interno .js e .css file, rispettivamente. Sempre.

Naturalmente, in molti casi, potrebbero essere necessarie alcune conoscenze aggiuntive per valutare correttamente la situazione. Ciò che conta di più è cominciare a pensare a queste cose e ad evitare il principio "esso (tipo) funziona, quindi va bene."Invece, chiedi sempre a te stesso, cosa significa in realtà il codice che sto scrivendo?"


Conclusione

La violazione di un contratto garantisce la rottura della cooperazione.

La cooperazione dipende sempre dallo sforzo di entrambe le parti. La maggior parte dello sviluppo del software si riduce alla cooperazione: cooperazione tra produttori di hardware, programmatori di sistemi, sviluppatori di browser, autori di librerie, sviluppatori di siti Web e molti altri. La violazione di un contratto garantisce la rottura della cooperazione.

La semantica del codice è uno di questi contratti. Prenditene cura per il vostro bene!


Le note

Semantico: Il termine "semantico" è spesso frainteso. Nel contesto di questo articolo, uso il termine per distinguere il significato del codice dal risultati prodotti dal codice. Ad esempio, il significato semantico di a il tag è rappresentazione di un link, mentre il significato semplice e pratico di ciò è testo cliccabile, sottolineato.

In senso stretto, un identificatore di frammento vuoto # potrebbe essere considerato valido in questo contesto. Questo aspetto tecnico, tuttavia, manca il punto che faccio nell'articolo.