Si dovrebbe creare un'architettura sottostante per aumentare la flessibilità, in anticipo o quando necessario? [chiuso]

1

In questa domanda Ho chiesto: il costo di progettare più livelli di astrazione per consentire un accoppiamento libero vale i vantaggi, o no?

La gente ha detto che spesso ne vale la pena, ma si dovrebbe sentire se la sua applicazione utilizzerà effettivamente questo progetto sottostante più tardi, o se sarà solo una perdita di tempo.

La mia nuova domanda è:

Si dovrebbe creare l'infrastruttura per consentire flessibilità e manutenibilità in anticipo - rendendo così lo sviluppo "più pulito" e più "organizzato", man mano che le cose vengono sviluppate sull'infrastruttura esistente e sui livelli di astrazione?

Con questo approccio, tu desing l'infrastruttura sottostante mentre non hai molta conoscenza su come le cose verranno effettivamente implementate in seguito. Pertanto, potresti codificare cose che potrebbero non essere utilizzate in seguito e sprecare il tuo tempo. Ma lo sviluppo sarà più pulito e più organizzato.

O dovresti creare un'infrastruttura per aumentare la flessibilità e rendere le cose più liberamente accoppiate, durante l'implementazione di qualcosa - quindi sprecare meno tempo su cose che potrebbero non essere effettivamente utilizzate in seguito?

Questo approccio ti impedisce di codificare cose che non saranno utilizzate, ma ti costringe a progettare i livelli di astrazione e le strutture per il codice esistente , modificando il codice esistente, invece di codificare i disegni sottostanti < strong> prima che codifica il codice che utilizza questi disegni.

Esempio per l'approccio 1: "Ok, ora iniziamo a fare questa parte relativamente grande dell'applicazione.Questa parte avrà generalmente a che fare con la reazione a un paio di GUI. Facciamo un livello sottostante di astrazione per questa parte del programma, da utilizzare successivamente quando la implementiamo. "

Esempio di approccio 2: "Ok, sono nel bel mezzo della progettazione di questa parte del programma. Mentre ci lavoro, vedo che questa parte è meglio accoppiata liberamente. Facciamo un altro livello di astrazione per consentirlo e modificare questo codice per utilizzare quel livello di astrazione ".

Quale approccio ha più senso o è più comune?

    
posta Aviv Cohn 20.03.2014 - 14:41
fonte

3 risposte

5

Francamente, entrambi.

È pressoché impossibile aggiungere livelli di astrazione dopo che tutto il codice è stato scritto e legato insieme in dozzine di punti. Purtroppo, è anche quasi impossibile ottenere tutti i livelli di astrazione giusti senza farlo effettivamente e vedere dove vanno le cose.

Quindi, in pratica, finisci per fare entrambe le cose. All'inizio aggiungi un'astrazione, cercando di creare un confine tra l'essere flessibile e l'over-engineering. Crei flessibilità laddove è molto probabile che sia necessario, o dove sarebbe catastrofico se dovessi sbagliare nella tua ipotesi. Per farla breve, riduci il rischio.

E poi, aggiungi o rimuovi l'astrazione nel tempo. Il refactoring è la chiave per rendere il codice "adatto". A volte trovi che le cose sono troppo complesse. A volte trovi che le cose sono troppo accoppiate. Pulisci nel tempo.

Questo tipo di sensazione per quanto è "abbastanza", e dove l'astrazione si trova è l'abilità chiave che si sviluppa nel tempo mentre progetta e vedi come hanno successo (o più spesso, falliscono ).

    
risposta data 20.03.2014 - 21:57
fonte
9

Consiglierei contro l'approccio 1. Scrivere il codice è un processo di scoperta - proprio come nessun piano sopravvive al contatto con il nemico, ogni progetto avrà difetti che vengono catturati solo quando inizi a implementarlo. Inoltre, puoi astrarre qualsiasi cosa in un numero arbitrario di direzioni e livelli. Se progetti per troppi "what-if", la tua architettura non sarà allineata alle tue esigenze; se preso abbastanza lontano, finisci con cose ridicole come Decima regola di Greenspun o Inner-Platform Effect (pensaci - se tutto è personalizzabile, quello che ti rimane è un linguaggio di programmazione.)

Inoltre, stai inseguendo un bersaglio mobile (cambiando i requisiti). Anche se miracolosamente ottieni il design corretto ora , non c'è alcuna garanzia che sarà comunque pertinente in seguito, come hai detto tu.

In breve, è una pendenza scivolosa. Non fornisce un valore immediato e ci sono buone probabilità che ti guidi nella direzione sbagliata.

    
risposta data 20.03.2014 - 15:05
fonte
1

La comunità Python ha questo meraviglioso artefatto: "Guido's Time Machine". Cioè, molti si meravigliano della lungimiranza di Guido Van Rossum nell'impostare sintassi e meccanismi in Python che hanno dimostrato di funzionare in modo molto pulito e intuitivo nel tempo.

Tuttavia, non tutti hanno una macchina del tempo e anticipare i requisiti può essere complicato.

In agile, la regola è "programma vicino ai requisiti". In TDD è "la soluzione più semplice che funzioni".

Tuttavia, esiste un equilibrio tra l'implementazione della forza bruta e l'astrazione per anticipare i requisiti futuri.

IMHO è importante per a) tenere d'occhio le astrazioni per fornire un codice pulito, flessibile ed estensibile, e b) fare attenzione a trasformare il progetto in una palude di infrastruttura sovra-generalizzata che in realtà non em > fai qualsiasi cosa.

Un sacco di tempo, lavorerò sulle cose di larghe vedute nel mio tempo libero nei miei progetti collaterali. Ma continuo a tremare nelle riunioni quando un ingegnere, a qualsiasi livello di esperienza, si entusiasma per un meccanismo che risolverà i problemi del mondo.

Alla fine della giornata, assicurati di mettere la funzionalità di fronte ai clienti. Ma mantieni nitidi i tuoi poteri di astrazione con un'applicazione mirata.

    
risposta data 20.03.2014 - 21:38
fonte

Leggi altre domande sui tag