Troppa astrazione può essere cattiva?


46

Come programmatori, ritengo che il nostro obiettivo sia fornire buone astrazioni sul modello di dominio e sulla logica di business forniti. Ma dove dovrebbe fermarsi questa astrazione? Come fare il compromesso tra l'astrazione e tutti i suoi benefici (flessibilità, facilità di modifica, ecc.) E facilità di comprensione del codice e di tutti i suoi benefici.

Credo di tendere a scrivere codice troppo astratto e non so quanto sia buono; Tendo spesso a scriverlo come se fosse una specie di micro-framework, che consiste di due parti:

  1. Micro-moduli collegati nel micro-quadro: questi moduli sono facili da capire, sviluppare e mantenere come singole unità. Questo codice rappresenta sostanzialmente il codice che svolge effettivamente le funzioni funzionali, descritto nei requisiti.
  2. Codice di connessione; ora qui credo che si pone il problema. Questo codice tende ad essere complicato perché a volte è molto astratto ed è difficile da capire all'inizio; ciò deriva dal fatto che è solo pura astrazione, la base nella realtà e la logica aziendale vengono eseguite nel codice presentato 1; da questo motivo non è previsto che questo codice venga modificato una volta testato.

È un buon approccio alla programmazione? Che, avendo cambiare il codice molto frammentato in molti moduli e molto facile da capire e un codice che non cambia molto complesso dall'astrazione POV? Se tutto il codice fosse uniformemente complesso (ovvero il codice 1 più complesso e interconnesso e il codice 2 più semplice) in modo che chiunque lo guardi possa capirlo in un ragionevole lasso di tempo ma il cambiamento è costoso o la soluzione presentata sopra è buona, dove "cambiare codice" è molto facile da capire, eseguire il debug, cambiare e "collegare il codice" è un po 'difficile.

Nota: non si tratta di leggibilità del codice! Entrambi i codici 1 e 2 sono leggibili, ma il codice 2 viene fornito con astrazioni più complesse mentre il codice 1 viene fornito con astrazioni semplici.


3
Commenti e nomi chiari vengono inventati per accelerare il tempo necessario per comprendere il codice complesso. Va benissimo che il tuo codice di livello inferiore sia più complesso; ad un certo livello, quasi sicuramente stai chiamando un livello molto più complesso e molto più basso.
DougM,

25
"Troppo" è male per definizione.
Jon Purdy,

@JimmyHoffa: devo tenere quei tipi al loro posto. E non essere geloso, non riesco a scrivere Haskell tutto il giorno. In realtà è principalmente PHP, JavaScript e OCaml.
Jon Purdy,

Risposte:


78

Le prime parole di TC ++ PL4:

Tutti i problemi nell'informatica possono essere risolti da un altro livello di riferimento indiretto, ad eccezione del problema di troppi livelli di riferimento indiretto. - David J. Wheeler

(David Wheeler era il mio consulente di tesi. La citazione senza l'importante ultima riga è talvolta chiamata "La prima legge dell'informatica.")


6
E come fai a sapere quando hai troppi livelli di indiretta? Tenderei a dire che viene fornito con esperienza, ma un programmatore più esperto capisce facilmente più riferimenti indiretti, quindi non vede un problema con troppi livelli.
m3th0dman,

2
@ m3th0dman: hai il giusto livello di astrazione quando diventa facile apportare modifiche in futuro. Naturalmente, puoi anche chiederti come sai quando ciò accadrà, che semplicemente ripete il ciclo di domande in un modo diverso.


1
questa domanda è come dipendente dal programmatore .. avrai programmatori complessi che capiranno la tua pazza architettura a 8 livelli e la troveranno geniale, mentre altri programmatori semplici ma fluidi la troveranno ridicola e discuteranno della tua pazza 8 livelli progetto a più livelli ... è qui che la documentazione paga, non solo ti consente di documentare il tuo codice, ma ti consente di difenderlo
Ryan,

1
perdona la mia ignoranza, ma non capisco "TC ++ PL4"
LastTribunal

30

Sì, sicuramente. Il fatto è che nessuna astrazione è perfetta. Tutti i dettagli del livello in cui si trovano le astrazioni sono lì per una ragione, e può semplificare molte cose, ma se quella complessità non fosse necessaria ad un certo punto, probabilmente non sarebbe lì in primo luogo. E questo significa che ad un certo punto, ogni astrazione colerà in qualche modo.

Ed è qui che sta il vero problema. Quando le astrazioni falliscono, più ne hai stratificato tra il codice che hai scritto e ciò che sta realmente accadendo, più è difficile capire il problema e risolverlo, perché ci sono più posti in cui il problema potrebbe trovarsi. E più strati ci sono, più devi sapere per rintracciarlo.


1
"E questo significa che ad un certo punto, ogni astrazione perderà in qualche modo.": Vero. Un'astrazione migliore è quella che perde meno spesso.
Giorgio,

11
Alla luce della risposta di Bjarne (e riferendosi alla pagina wiki di David Wheeler ), forse puoi cambiare l'attribuzione del tuo preventivo? :)
congusbongus,

2
@CongXu: A proposito, ci sono andato dall'altra parte: cercare su Google "Citazioni di Bjarne Stroustrup" e non ho trovato un singolo riferimento di Bjarne dopo aver pronunciato la frase "aggiungere un altro livello di indiretto" ... Non conclusivo, ma certo rende altamente improbabile che sia stato il primo a pronunciarlo.
Marjan Venema,

1
Più strati di astrazione significano astrazioni semplici e quindi meno perdite per astrazione. Quindi in una formulazione matematica (ovviamente, senza alcuna prova) la somma delle perdite di astrazione potrebbe essere costante al variare del numero di livelli di astrazione.
m3th0dman,

2
Una volta ho ingenuamente preso il consiglio di un anziano per aggiungere un'astrazione dove non era necessaria. Non è mai stato usato oltre quello che volevo fare in primo luogo.
Cees Timmerman,

15

Si assolutamente.

L'analogia che mi piace usare per spiegare la programmazione è quella di un sarto. Quando si prepara un abito, un buon Sarto lascerà sempre una piccola quantità di tessuto in posizioni strategiche all'interno del capo per consentire al capo di essere portato dentro o fuori senza cambiare la sua forma o struttura generale.

Il buon sarto non lascia risme di tessuto ad ogni cucitura solo nel caso in cui ti capiti di far crescere un terzo braccio o rimanere incinta. Troppo materiale nei posti sbagliati renderà un indumento inadatto, e mal indossato, il tessuto extra semplicemente ostacola il normale utilizzo. A poca stoffa e il capo è incline alle lacrime e non sarà in grado di essere modificato per far fronte a piccole modifiche al fisico di chi lo indossa, influenzando il modo in cui si trova il capo.

Forse un giorno, il nostro buon sarto sarà incaricato di fare un vestito così stretto che deve cucire indossandolo. E forse al nostro buon sarto viene chiesto di indossare abiti per la maternità, dove stile e vestibilità sono secondi per comfort ed espandibilità. Ma prima di intraprendere uno di quei lavori speciali un buon Sarto sarebbe abbastanza saggio da rendere tutti consapevoli dei compromessi che sono stati fatti per raggiungere quegli obiettivi.

A volte questi compromessi sono la strada giusta da prendere e le persone sono disposte ad accettarne le conseguenze. Ma nella maggior parte dei casi, l'approccio di lasciare un po 'dove conta di più supererà qualsiasi beneficio percepito.

Quindi, riconducendolo all'astrazione. È assolutamente possibile che ci siano troppi strati di astrazione, proprio come è possibile che abbia troppo poco. La vera arte del programmatore, come i nostri amici su misura, è quella di lasciare un po 'dove conta di più.

Tornando sull'argomento.

Il problema con il codice di solito non è l'astrazione, ma le dipendenze. Come hai sottolineato, è il codice che collega gli oggetti discreti che è un problema, perché c'è una dipendenza implicita tra di loro. Ad un certo punto la comunicazione tra le cose deve solo essere concreta, ma giudicare dove quel punto è di solito richiede alcune congetture.

Detto questo "Micro" qualsiasi cosa di solito è un'indicazione che hai sovrastimato il layout del tuo oggetto e probabilmente stai usando Tipo come sinonimo di ciò che dovrebbe essere Dati . Avere meno cose significa anche meno dipendenze necessarie per comunicare tra di loro.

Sono un grande fan della messaggistica asincrona tra i sistemi per questo motivo. Si finisce con due sistemi dipendenti dal messaggio , piuttosto che l'uno dall'altro. Ti offre un accoppiamento meno stretto tra i sistemi di comunicazione. A quel punto, se devi avere una dipendenza tra i sistemi devi considerare se hai i bit che dipendono nei posti giusti. Ed è spesso il caso che tu non lo faccia.

Infine, il codice complicato sarà complicato. Spesso non c'è modo di aggirare questo. Ma il codice che ha meno dipendenze è molto più facile da capire di quello che si basa su vari stati esterni.


2
+1 per "Il buon sarto non lascia risme di tessuto ad ogni cucitura solo nel caso in cui ti capiti di crescere un terzo braccio o rimanere incinta". Spesso tendiamo a progettare software in questo modo, purtroppo.
Kemoda,

Insieme alla comprensibilità, si può anche trovare l'astrazione utile quando si piega una linea curva in una retta. Significa che stai riducendo la complessità e / o l'entropia con l'astrazione. Forse qualcosa come un gestore di dati di tipo Curry in cui il grasso che si rade è ancora utile in seguito.
Cody,

13

Ritengo che il nostro obiettivo sia fornire buone astrazioni sul modello di dominio e sulla logica aziendale indicati.

Ho una visione diversa: il nostro obiettivo è risolvere un problema aziendale. Le astrazioni sono solo una tecnica per organizzare una soluzione. Un'altra risposta usa l'analogia di un sarto che fa i vestiti. Ho un'altra analogia a cui mi piace pensare: uno scheletro. Il codice è come uno scheletro e le astrazioni sono le articolazioni tra le ossa. Se non si hanno articolazioni, si finisce con un solo osso che non può muoversi e che è inutile. Ma se hai troppe articolazioni, finisci con una pila di gelatina sciatta che non riesce a reggersi da sola. Il trucco è trovare il giusto equilibrio - abbastanza articolazioni per consentire il movimento, ma non così tanto da non avere una forma o una struttura definita.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.