Astrazione e composizione

Smoke Art Cubes to Smoke - MattysFlicks - (CC BY 2.0)
Nota: fa parte della serie "Composing Software" (ora un libro!) Sull'apprendimento da zero della programmazione funzionale e delle tecniche software compositive in JavaScript ES6 +. Rimanete sintonizzati. C'è molto di più a venire!

Più maturo nello sviluppo di software, più apprezzo i fondamenti - intuizioni che sembravano banali quando ero un principiante, ma ora detengono un significato profondo con il beneficio dell'esperienza.

"Nell'arte marziale del Karate [...] il simbolo di orgoglio per una cintura nera è di indossarlo abbastanza a lungo in modo tale che la tintura sfuma al bianco da simboleggiare il ritorno allo stato principiante." ~ John Maeda, "Le leggi della semplicità : Design, tecnologia, impresa, vita "

L'astrazione è "il processo di considerare qualcosa indipendentemente dalle sue associazioni, attributi o accompagnamenti concreti", secondo il dizionario di Google.

La parola astrazione deriva dal verbo latino asstrahere, che significa "tirare via". Mi piace questa intuizione. L'astrazione riguarda la rimozione delle cose, ma cosa stiamo rimuovendo e a che scopo?

A volte mi piace tradurre le parole in altre lingue e poi tradurle in inglese per avere un'idea di altre associazioni a cui comunemente non pensiamo in inglese. Quando traduco "astrazione" in yiddish e viceversa, il risultato è "distratto". Mi piace anche questo. Una persona distratta sta correndo con il pilota automatico, non sta attivamente pensando a quello che sta facendo ... lo sta solo facendo.

L'astrazione ci consente di correre sul pilota automatico, in sicurezza. Tutto il software è automazione. Dato abbastanza tempo, tutto ciò che fai su un computer, potresti fare con carta, inchiostro e piccioni viaggiatori. Il software si occupa solo di tutti i piccoli dettagli che richiederebbero troppo tempo per essere eseguiti manualmente.

Tutto il software è astrazione, che nasconde tutto il duro lavoro e i dettagli insensati mentre ne ricaviamo i benefici.

Molti processi software vengono ripetuti ancora e ancora. Se, durante la fase di decomposizione del problema, decidessimo di reimplementare ripetutamente le cose ripetute, ciò richiederebbe molto lavoro inutile. Almeno sarebbe sciocco. In molti casi, sarebbe poco pratico.

Invece, rimuoviamo la duplicazione scrivendo un componente di qualche tipo (una funzione, un modulo, una classe, ecc ...), dandogli un nome (identità) e riutilizzandolo tutte le volte che vogliamo.

Il processo di decomposizione è il processo di astrazione. L'astrazione riuscita implica che il risultato è un insieme di componenti utili e ricomposibili in modo indipendente. Da ciò otteniamo un importante principio dell'architettura software:

Le soluzioni software dovrebbero essere scomponibili nelle loro parti componenti e ricomposibili in nuove soluzioni, senza modificare i dettagli di implementazione dei componenti interni.

L'astrazione è l'atto di semplificazione

"La semplicità consiste nel sottrarre l'ovvio e aggiungere il significativo." ~ John Maeda, "Le leggi della semplicità: design, tecnologia, impresa, vita"

Il processo di astrazione ha due componenti principali:

  • La generalizzazione è il processo per trovare somiglianze (l'ovvio) in schemi ripetuti e nascondere le somiglianze dietro un'astrazione.
  • La specializzazione è il processo di utilizzo dell'astrazione, che fornisce solo ciò che è diverso (il significativo) per ogni caso d'uso.

L'astrazione è il processo di estrazione dell'essenza sottostante di un concetto. Esplorando un terreno comune tra problemi diversi di domini diversi, impariamo a uscire dal nostro spazio di testa per un momento e vedere un problema da una prospettiva diversa. Quando vediamo l'essenza di un problema, scopriamo che una buona soluzione può applicarsi a molti altri problemi. Se codifichiamo bene la soluzione, possiamo ridurre radicalmente la complessità della nostra applicazione.

"Se tocchi una cosa con profonda consapevolezza, tocchi tutto." ~ Thich Nhat Hanh

Questo principio può essere utilizzato per ridurre radicalmente il codice richiesto per creare un'applicazione.

Astrazione nel software

L'astrazione nel software assume molte forme:

  • algoritmi
  • Strutture dati
  • moduli
  • Classi
  • Frameworks

E il mio preferito personale:

“A volte, l'implementazione elegante è solo una funzione. Non è un metodo Non una lezione. Non un quadro. Solo una funzione. ”~ John Carmack (Id Software, Oculus VR)

Le funzioni fanno grandi astrazioni perché possiedono le qualità essenziali per una buona astrazione:

  • Identità: la capacità di assegnargli un nome e di riutilizzarlo in contesti diversi.
  • Composizione - La capacità di comporre semplici funzioni per formare funzioni più complesse.

Astrazione attraverso la composizione

Le funzioni più utili per l'astrazione nel software sono funzioni pure, che condividono caratteristiche modulari con funzioni matematiche. In matematica, una funzione con gli stessi input restituirà sempre lo stesso output. È possibile vedere le funzioni come relazioni tra input e output. Dato un input A, una funzione f produrrà B come output. Si potrebbe dire che f definisce una relazione tra A e B:

f: A -> B

Allo stesso modo, potremmo definire un'altra funzione, g, che definisce una relazione tra B e C:

g: B -> C

Ciò implica un'altra funzione h che definisce una relazione direttamente da A a C:

h: A -> C

Tali relazioni formano la struttura dello spazio problematico e il modo in cui componi le funzioni nella tua applicazione costituisce la struttura della tua applicazione.

Le buone astrazioni semplificano nascondendo la struttura, allo stesso modo in cui h riduce A -> B -> C fino a A -> C.

Come fare di più con meno codice

L'astrazione è la chiave per fare di più con meno codice. Ad esempio, immagina di avere una funzione che aggiunge semplicemente due numeri:

const add = (a, b) => a + b;

Ma lo usi spesso per incrementare, potrebbe avere senso fissare uno di quei numeri:

const a = add (1, 1);
const b = add (a, 1);
const c = add (b, 1);
// ...

Possiamo curry la funzione di aggiunta:

const add = a => b => a + b;

Quindi crea un'applicazione parziale, applicando la funzione al suo primo argomento e restituendo una nuova funzione che accetta l'argomento successivo:

const inc = add (1);

Ora possiamo usare inc invece di aggiungere quando dobbiamo incrementare di 1, il che riduce il codice richiesto:

const a = inc (1);
const b = inc (a);
const c = inc (b);
// ...

In questo caso, inc è solo una versione specializzata di add. Tutte le funzioni al curry sono astrazioni. In effetti, tutte le funzioni di ordine superiore sono generalizzazioni che puoi specializzare passando uno o più argomenti.

Ad esempio, Array.prototype.map () è una funzione di ordine superiore che riassume l'idea di applicare una funzione a ciascun elemento di un array per restituire un nuovo array di valori elaborati. Possiamo scrivere la mappa come una funzione al curry per renderlo più ovvio:

const map = f => arr => arr.map (f);

Questa versione di map utilizza la funzione di specializzazione e quindi restituisce una versione specializzata di se stessa che accetta l'array da elaborare:

const f = n => n * 2;
const doubleAll = map (f);
const raddoppiato = doubleAll ([1, 2, 3]);
// => [2, 4, 6]

Nota che la definizione di doubleAll ha richiesto una quantità banale di codice: map (f) - tutto qui! Questa è l'intera definizione. Partendo da astrazioni utili come i nostri mattoni, possiamo costruire comportamenti abbastanza complessi con pochissimo nuovo codice.

Conclusione

Gli sviluppatori di software trascorrono le loro intere carriere a creare e comporre astrazioni, molte senza una buona conoscenza di astrazione o composizione.

Quando crei astrazioni, dovresti essere deliberato a riguardo e dovresti essere consapevole delle buone astrazioni che sono già state rese disponibili per te (come la mappa, il filtro e la riduzione sempre utili). Impara a riconoscere le caratteristiche di buone astrazioni:

  • Semplice
  • Conciso
  • riutilizzabile
  • Indipendente
  • Scomponibile
  • Recomposable

Maggiori informazioni su EricElliottJS.com

Le lezioni video sulla programmazione funzionale sono disponibili per i membri di EricElliottJS.com. Se non sei un membro, iscriviti oggi.

Eric Elliott è autore di "Programmazione di applicazioni JavaScript" (O’Reilly) e cofondatore della piattaforma di tutoraggio software, DevAnywhere.io. Ha contribuito alle esperienze software per Adobe Systems, Zumba Fitness, The Wall Street Journal, ESPN, BBC e i migliori artisti della registrazione tra cui Usher, Frank Ocean, Metallica e molti altri.

Lavora da remoto ovunque con la donna più bella del mondo.