DanLevy.net

Attenti alle Persone Mono-Missione

Così puro che fa male

Il Single Responsibility Principle è una di quelle idee che suona così sensata da poter superare indenne il tuo giudizio.

Fai una cosa. Falla bene. Mantieni i moduli focalizzati. Dai al codice un motivo per cambiare. Buon consiglio.

Poi qualcuno trasforma il consiglio in un metro di misura e inizia a dichiarare che qualsiasi funzione superiore a cinque righe è un code smell.

Il problema non è SRP. Il problema è trattare “piccolo” come un sostituto di “coesivo.”

A quel punto hai incontrato le Persone Mono-Missione: sviluppatori che non hanno esattamente torto sulla modularità, ma hanno confuso i confini utili con la frammentazione massima.

Violenza nell’Architettura Software
Componenti, componenti ovunque

I. L’Idea Utile Sottostante

Aggiungere una singola checkbox a un form dovrebbe idealmente interessare solo un file. Non 8 file attraverso 5 directory… ti sto guardando, React/Redux.

Quando SRP è applicato con giudizio, aiuta. Le unità di codice focalizzate su un singolo compito concettuale sono più facili da comprendere. I test possono mirare al comportamento a un confine sensibile. Moduli chiari rendono più facile cambiare una parte del sistema senza trascinare il resto dell’applicazione nella stanza.

Anche i classici esempi Unix sono più pragmatici dello slogan. ls elenca i file, sì, ma coordina anche chiamate come opendir, readdir, closedir e stat. L’unità utile non è l’operazione più piccola possibile. L’unità utile è la cosa coerente più piccola che risolve il compito.

La filosofia Unix originale riguardava la composizione e la semplicità, non il ridurre tutto a una singola funzione o file.

Questa distinzione è importante. “Una responsabilità” non è la stessa cosa di “una riga di comportamento.”

II. Over-Abstraction: Quando la Semplicità Diventa Caos

Il nostro architetto insiste che ogni funzione più lunga di 5 righe è un ‘code smell’. Il nostro codebase ora puzza leggermente di disperazione clueless.

La modalità di fallimento è facile da notare dopo che ha già peggiorato la tua settimana.

Il codebase ha più file, ma meno forma. Ogni helper ha un helper. Ogni concetto è stato diviso tra cartelle nominate per ruoli tecnici invece che per significato del prodotto. Aggiungere una checkbox richiede di toccare un componente, un hook, un selettore, un’azione, un reducer, una costante, un fixture di test e un barrel export che esiste principalmente per evitare che i percorsi di import sembrino colpevoli.

Nessuna via di fuga per questo modello di lavoro infinito
Componenti, componenti ovunque

Cosa ha comprato tutta quella purezza?

Ho fissato l’abisso di codebase dove una funzione semplice da 100 righe è stata vivisezionata attraverso 15+ file, ciascuno un “puro” piccolo angelo contenente magari una o due funzioni. Il raggio cognitivo esplosivo del cercare di tenere quel pasticcio nella tua testa ha completamente negato qualsiasi vantaggio teorico dalla separazione. Non era più semplice; era solo sparso.

III. Il Pedaggio della Perfezione: Impatto sugli Sviluppatori

Passiamo più tempo a dibattere sulla struttura dei file e sulle convenzioni di naming che a spedire effettivamente funzionalità. È questo Agile?

Così disordinato che rasenta l’arte
Così disordinato che rasenta l'arte

Questa frammentazione patologica non è solo un problema estetico. Cambia il modo in cui gli sviluppatori spendono la loro attenzione:

Il Drenaggio della Produttività: Dimentica il debito tecnico; questo è debito organizzativo accumulato attraverso un nesting ossessivo-compulsivo di directory. Ogni modifica minore diventa uno scavo archeologico attraverso strati di astrazione. Il tempo scompare nel buco nero di cd .. e grep.

La Tassa dei Test: Invece di fornire fiducia, la suite di test diventa una fonte di attrito. Le ore si sciolgono fissando test rotti da refactor banali, test che erano troppo strettamente accoppiati ai dettagli microscopici che avrebbero dovuto verificare.

Il Carico Cognitivo: C’è un limite duro a quante informazioni disconnesse un cervello umano può gestire. Forzare gli sviluppatori a ricostruire il flusso del programma da una dozzina di file sparsi ostacola attivamente la comprensione e rende più difficili le modifiche sicure.

IV. Abbracciare il Pragmatismo: Un’Alternativa Pratica

Ho suggerito di mettere due funzioni correlate nello stesso file. La stanza ha reagito come se avessi proposto di cancellare staging. — Un lettore purista in recupero

La via di fuga non è abbandonare SRP. La risposta è applicarlo al giusto livello di significato.

Ecco come appare nella pratica:

L’obiettivo non è la perfezione teorica degna di una tesi di dottorato; è creare codice che i tuoi colleghi (e il te futuro) possano navigare, comprendere e modificare senza voler dare fuoco all’edificio.

A volte questo significa che un file è lungo 200 righe invece di 50. A volte una funzione gestisce il fetching dei dati e li trasforma leggermente. A volte una classe ha due responsabilità così strettamente accoppiate che dovrebbero vivere insieme. Se rende il sistema più facile da usare nel complesso, è probabilmente la scelta giusta.

Rimani relentlessly focalizzato sulle domande pratiche:

V. Conclusione: Promuovere Codice Coesivo e Manutenibile

Il Single Responsibility Principle è uno strumento utile. Non è un mandato per polverizzare il tuo codebase in polvere atomica. Come qualsiasi strumento, il suo valore dipende dal giudizio della persona che lo usa.

Quindi quando incontri le Persone Mono-Missione, pronte a fare guerra a qualsiasi funzione che osi superare tre righe, fai un respiro. Ricorda la checkbox da 12 file.

Il nostro lavoro non è costruire funzioni snowflake teoricamente immacolate. Il nostro lavoro è costruire software che funziona, risolve problemi e non punisce la prossima persona che deve toccarlo.

Rimani pragmatico. Focalizzati sui risultati. Non lasciare che la ricerca della purezza perfetta diventi il nemico del codice manutenibile. La tua sanità mentale e la velocità del tuo team dipendono da questo.

¹ L’ironia è che raggiungere effettivamente lo scopo singolo ai livelli più bassi richiede un’immensa complessità nascosta appena sotto la superficie.

² Stiamo parlando di purezza concettuale qui: l’idea che una funzione dovrebbe fare solo “una cosa” logicamente. Non confonderlo con il concetto di “funzione pura” della programmazione funzionale senza effetti collaterali, che è un’idea diversa, anche se a volte correlata.