Domanda

Una delle più frequenti argomenti che sento per non aderire ai principi SOLID in object il design oriented è YAGNI (anche se l'arguer spesso non chiama così):

"E 'OK che ho messo sia la caratteristica X e Y funzione nella stessa classe. E' così semplice perché preoccuparsi l'aggiunta di una nuova classe (vale a dire complessità)."

"Sì, posso mettere tutta la mia logica di business direttamente nel codice della GUI è molto più facile e veloce. Questo sarà sempre l'unica interfaccia grafica ed è altamente improbabile che significativi nuovi requisiti potrà mai entrare."

"Se nel caso improbabile di nuove esigenze mio codice viene troppo disordinato riesco ancora a refactoring per il nuovo requisito. Così il vostro argomento 'Che cosa se in seguito bisogno di ...' non conta."

Qual 'è la maggior parte degli argomenti convincenti contro tale pratica? Come posso davvero show che si tratta di una pratica costosa, soprattutto a qualcuno che non ha troppa esperienza nello sviluppo di software.

È stato utile?

Soluzione

Design è la gestione e l'equilibrio dei trade-off YAGNI e solido non sono in conflitto:. Il primo dice quando per aggiungere funzionalità, quest'ultima dice come, ma entrambi guidano il processo di progettazione. Le mie risposte, qui di seguito, a ciascuna delle vostre citazioni specifiche usare i principi sia da YAGNI e solido.

  
      
  1. È tre volte più difficile da costruire componenti riutilizzabili come uso singola   componenti.
  2.   
  3. Un componente riutilizzabile dovrebbe essere processato in tre diversi   applicazioni prima sarà sufficientemente generali accettare in un riutilizzo   biblioteca.
  4.   
     

- Robert Glass' Regolamento Tre , fatti e Fallacies di Ingegneria del Software

Rifattorizzare in componenti riutilizzabili ha l'elemento chiave della prima trovare lo stesso scopo in più luoghi, e poi di spostarlo. In questo contesto, YAGNI applica per inlining tale scopo, ove necessario, senza preoccuparsi di possibile duplicazione, invece di aggiungere caratteristiche generici o riutilizzabili (classi e funzioni).

Il modo migliore, nel progetto iniziale, per mostrare quando YAGNI non si applica è quello di individuare le esigenze concrete. In altre parole, fare un po 'di refactoring prima di scrivere codice per dimostrare che la duplicazione non è solo possibile, ma già esiste:. Ciò giustifica lo sforzo supplementare


  

Sì, posso mettere tutta la mia logica di business direttamente nel codice della GUI è molto più facile e veloce. Questa sarà sempre la sola GUI ed è altamente improbabile che i nuovi requisiti signifcant potrà mai entrare.

E 'davvero l'unica interfaccia utente? C'è uno sfondo in modalità batch pianificato? Ci sarà mai un'interfaccia web?

Qual è il vostro piano di test, e si sarà testando le funzionalità di back-end senza interfaccia grafica? Cosa farà l'interfaccia grafica facile per voi di prova, dal momento che di solito non si vuole essere testare codice esterno (come ad esempio controlli GUI piattaforma-generici) e invece concentrato sul progetto.

  

E 'OK che ho messo sia la caratteristica X e Y funzione nella stessa classe. E 'così semplice perché preoccuparsi l'aggiunta di una nuova classe (vale a dire la complessità).

Si può indicare un errore comune che deve essere evitato? Alcune cose sono abbastanza semplici, come ad esempio la squadratura un numero (x * x vs squared(x)) per un esempio eccessivamente semplice, ma se si può indicare un concreto errore qualcuno ha fatto, soprattutto nel vostro progetto o da coloro che sulla vostra squadra si può dimostrare come una classe o una funzione comune eviteranno che in futuro.

  

Se, nel caso improbabile di nuove esigenze, il mio codice diventa troppo ingombra ancora posso refactoring per il nuovo requisito. Così il vostro "Che se in seguito bisogno di ..." l'argomento non conta.

Il problema qui è l'assunzione di "improbabile". Sei d'accordo è improbabile? Se è così, siete d'accordo con questa persona. In caso contrario, la vostra idea di progettazione non è d'accordo con questo person's-risolvere che discrepanza risolverà il problema, o almeno vi mostrerà dove andare. :)

Altri suggerimenti

Sembra che tu stia a discutere con un muro di mattoni. Sono un grande fan di YAGNI, ma allo stesso tempo, mi aspetto anche che il mio codice sempre essere utilizzato in almeno due punti: l'applicazione, e le prove. Ecco perché le cose come logica di business nel codice interfaccia utente non funzionano; non si può testare la logica di business separata del codice di interfaccia utente in quella circostanza.

Tuttavia, dalle risposte che stai descrivendo, suona come la persona è semplicemente disinteressato nel fare un lavoro migliore. A quel punto, nessun principio sta per aiutarli; vogliono solo fare il minimo possibile. Mi piacerebbe andare così lontano come a dire che non è YAGNI guidare le loro azioni, ma piuttosto la pigrizia, e tu solo non stanno andando a battere la pigrizia (quasi nulla può, ad eccezione di un manager minaccioso o la perdita di un posto di lavoro).

Mi piace pensare YAGNI in termini di "metà, non assed", per prendere in prestito la frase da 37signals ( https://gettingreal.37signals.com/ch05_Half_Not_Half_Assed.php ). Si tratta di limitare l'ambito di applicazione in modo da poter concentrarsi sul fare il maggior numero di cose importanti bene. Non è una scusa per ottenere sciatta.

logica di business nel GUI sente assed a me. A meno che il vostro sistema è banale, mi sarei sorpreso se la logica di business e GUI non hanno già cambiato in modo indipendente, più volte. Per questo si deve seguire la SRP ( "S" in SOLID) e refactoring -. YAGNI non si applica, perché già bisogno

L'argomento su YAGNI e inutili complessità assolutamente vale se si sta facendo il lavoro supplementare oggi per soddisfare esigenze future ipotetiche. Quando coloro "che cosa se poi abbiamo bisogno di ..." scenari non riescono a materializzarsi, sei bloccato con maggiori costi di manutenzione delle astrazioni che oggi si frappongono dei cambiamenti che effettivamente hanno. In questo caso, stiamo parlando di semplificare la progettazione, limitando la portata -. Fare la metà, invece di essere assed

Non c'è una risposta, o meglio, c'è una risposta né tu né tua forza interlocutore come:. Sia YAGNI e solido può essere approcci sbagliati

Il tentativo di andare per SOLID con un team inesperto, o una squadra con obiettivi di consegna stretti praticamente garanzie vi ritroverete con un costoso, mazzo sovra-ingegnerizzato di codice ... che non sarà solido, poco più-ingegnerizzato (aka il benvenuto al mondo reale).

Il tentativo di andare YAGNI per un progetto a lungo termine e la speranza si può refactoring in seguito funziona solo in misura (aka il benvenuto al mondo reale). eccelle YAGNI a proof-of-concept e dimostranti, ottenendo il mercato / contratto e quindi essere in grado di investire in qualcosa di più solido.

Hai bisogno di entrambi, in diversi punti nel tempo.

La corretta applicazione di questi principi spesso non è molto evidente e dipende molto dalla esperienza. Che è difficile da ottenere se non l'avete fatto da soli. Ogni programmatore avrebbe dovuto avere esperienze delle conseguenze facendo male, ma naturalmente sempre dovrebbe essere "non è il mio progetto".

Spiegare loro quale sia il problema, se non ascoltano e non sei in grado di farle ascoltare, lasciarli fare gli errori. Se siete troppo spesso quella di dover risolvere il problema, si dovrebbe lucidare il vostro curriculum.

Nella mia esperienza, è sempre una chiamata in giudizio. Sì, non si deve preoccupare di ogni piccolo dettaglio della vostra implementazione, e, talvolta, attaccare un metodo in una classe esistente è un accettabile, anche se brutta soluzione.

E 'vero che si può refactoring più tardi. Il punto importante è quello in realtà fare il refactoring . Quindi credo che il vero problema non è il compromesso di design occasionale, ma rimandando refactoring una volta diventa chiaro che c'è un problema. In realtà andare fino in fondo è la parte difficile (proprio come con molte cose nella vita ...).

Per quanto riguarda i punti individuali:

  

E 'OK che ho messo sia la caratteristica X   e presentano Y nella stessa classe. esso   è così semplice perché preoccuparsi l'aggiunta di una nuova   classe (complessità cioè).

I ricorda che avere tutto in una classe è più complesso (perché il rapporto tra i metodi è più intimo, e più difficile da capire). Avendo molte piccole classi non è complessa. Se si sente la lista è di arrivare a lungo, basta organizzarli in pacchetti, e andrà tutto bene :-). Personalmente, ho trovato che solo la divisione di una classe in due o tre classi può aiutare molto con la leggibilità, senza alcuna ulteriore modifica.

Non abbiate paura di piccole classi, non pungono; -).

  

Sì, posso mettere tutta la mia logica di business   direttamente nel codice della GUI è molto più   più facile e veloce. Questo sarà sempre   essere l'unico interfaccia grafica ed è altamente   improbabile che nuovi signifcant   requisiti potrà mai entrare.

Se qualcuno può dire "è altamente improbabile che i nuovi requisiti signifcant potrà mai entrare." con la faccia seria, credo che persona veramente, davvero ha bisogno di un controllo di realtà. Essere schietto, ma gentile ...

  

Se nel caso improbabile di nuovo   requisiti mio codice ottiene troppo   ingombra Posso ancora refactoring per il   nuovo requisito. Così il vostro 'cosa succede se si   necessità più tardi per ...' argomento non lo fa   count

Che ha qualche merito, ma solo se effettivamente fare refactoring più tardi. Così accettarlo, e tenerli alla loro promessa: -).

solidi principi permettono software di adattarsi al cambiamento - in entrambi i requisiti e cambiamenti Techical (nuovi componenti, ecc), due delle vostre argomentazioni sono per i requisiti immutabili:

  • "è altamente improbabile che i nuovi requisiti signifcant potrà mai entrare."
  • "Se nel caso improbabile di nuovi requisiti"

Questo potrebbe davvero essere vero?

Non v'è alcun sostituto per esperienza, quando si tratta di spese varie di sviluppo. Per molti professionisti Penso fare le cose nel schifoso, difficile da mantenere modo non si è mai comportato problemi per loro (ehi! La sicurezza del lavoro). Nel lungo termine di un prodotto Credo che queste spese diventano chiari, ma fare qualcosa per loro prima del tempo è di qualcun altro lavoro.

Ci sono alcuni altri grandi risposte qui.

Comprensibile, flessibili e capaci di correzioni e miglioramenti sono sempre cose che si sta per necessità. Infatti, YAGNI presuppone che si può tornare indietro e aggiungere nuove funzionalità, quando esso risulti necessario con relativa facilità, perché nessuno ha intenzione di fare qualcosa di pazzo come bunging funzionalità irrilevante in una classe (YAGNI in quella classe!) O spingendo la logica di business alla logica UI .

Non ci possono essere momenti in cui quello che sembra pazzesco ora era ragionevole in passato - a volte le linee di confine di UI vs imprese o tra i diversi gruppi di responsabilità che dovrebbero essere in una classe diversa non chiaro, o anche spostare lo sono. Ci possono essere momenti in cui tre ore di lavoro è assolutamente necessario nel tempo 2 ore. Ci sono momenti in cui la gente non effettuare la chiamata giusta. Per queste ragioni le pause occasionali a questo proposito che accadrà, ma sono in corso per ottenere nel modo di usare il principio YAGNI, non essere una causa di esso.

Test di qualità di unità, e non i test unitari medi test di integrazione, il codice necessario che aderisce alla SOLIDO. Non necessariamente al 100%, infatti raramente così, ma nel tuo esempio ripieno due caratteristiche in una sola classe farà Unit Testing più duro, rompe il principio di un'unica responsabilità, e rende la manutenzione del codice da neofiti squadra molto più difficile (come è molto più difficile da comprendere) .

Con i test di unità (assumendo una buona copertura di codice) sarete in grado di funzionalità di refactoring 1 sicuro e sicuro che non si romperà funzione 2, ma senza test di unità e con le caratteristiche di stessa classe (semplicemente di essere in pigro il tuo esempio) refactoring è rischioso nella migliore delle ipotesi, disastrosa nella migliore delle ipotesi.

Linea di fondo: seguire il principio KIS (mantenerlo semplice), o per l'intellettuale il principio KISS (KIS stupido). Prendere ogni caso in base al merito, non c'è una risposta globale, ma considerano sempre se altri programmatori hanno bisogno di leggere / mantenere il codice in futuro e il beneficio di test di unità in ogni scenario.

TLDR;

SOLID assume, si capisce (un po 'atleast), le future modifiche al codice, WRT SRP. Devo dire che è essere ottimisti circa la capacità di prevedere. YAGNI d'altra parte, assume la maggior parte delle volte non si conosce la futura direzione del cambiamento, che è pessimista sulla capacità di prevedere.

Ne segue che SOLIDO / SRP ti chiede di formare le classi per il codice in modo che si hanno motivo unico per il cambiamento. Per esempio. un piccolo cambiamento GUI o cambiamento ServiceCall.

YAGNI dice (se si vuole forza applicarlo in questo scenario), dal momento che non si sa cosa sta per cambiare, e se un cambiamento GUI causerà un cambiamento GUI + ServiceCall (simile Un cambiamento backend causando GUI + SeviceCall cambiamento), appena messo tutto quello che il codice in un'unica classe.

Risposta lunga:

Leggi il libro 'Agile Software Development, principi, modelli e pratiche'

sto mettendo breve estratto da esso circa SOLIDO / prezzo consigliato: "Se, [...] l'applicazione non sta cambiando in modi che causano le due responsabilità al cambiamento in tempi diversi, non c'è bisogno di separarli. In effetti, la separazione li avrebbero odore di complessità inutile.

C'è un corrolary qui. Un asse di cambiamento è un asse di cambiamento solo se si verificano le modifiche. Non è saggio applicare SRP-o qualsiasi altro principio, del resto, se non v'è alcun sintomo. "

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top