Questa non è davvero una risposta tanto quanto un lungo commento (perché queste risposte sono già state presentate).
Ho trovato che sforzarmi religiosamente per due fattori: interfacce pulite e utilizzabili e nessuna ripetizione hanno reso il mio codice molto migliore e nel tempo mi hanno reso un programmatore molto migliore.
A volte eliminare il codice ridondante è HARD, ti costringe a inventare alcuni schemi complicati.
Di solito analizzo ciò che DEVE cambiare, quindi rendi questo il mio obiettivo. Ad esempio, se si sta eseguendo una GUI su un client per aggiornare un database, a cosa è necessario aggiungere "Altro" (un altro controllo collegato al DB?) È necessario aggiungere una riga al DB e occorre la posizione del componente, il gioco è fatto.
Quindi, se questo è il tuo minimo indispensabile, non vedo NESSUN codice in questo - dovresti essere in grado di farlo senza toccare il tuo codice base. Questo è incredibilmente difficile da raggiungere, alcuni toolkit lo faranno (solitamente male), ma è un obiettivo. Quanto è difficile avvicinarsi? Non terribilmente. Posso farlo e lo ho fatto con codice zero in un paio di modi, uno è taggando i nuovi componenti della GUI con il nome della tabella nel DB, un altro creando un file XML - il file XML (o YAML se lo si odia XML) può essere davvero utile perché puoi collegare validatori e azioni speciali al campo, rendendo il pattern estremamente flessibile.
Inoltre, non ci vuole più tempo per implementare correttamente le soluzioni: dal momento in cui hai spedito la maggior parte dei progetti è effettivamente più economico.
Posso sottolineare che se ti affidi molto a Setters & Getters ("Bean Patterns"), Generics & Le classi interne anonime probabilmente NON codificano genericamente in questo modo. Negli esempi sopra, provare a forzare qualcuno di questi ti rovinerà davvero. Setter e amp; I getter ti obbligano a usare il codice per i nuovi attributi, Generics ti costringe a istanziare le classi (che richiede il codice) e amp; Le classi interiori anonime tendono a non essere facili da riutilizzare altrove. Se si sta veramente codificando genericamente, questi costrutti linguistici non sono male, ma possono rendere difficile la visualizzazione di un pattern. Per un esempio totalmente privo di senso:
user.setFirstName(screen.getFirstName());
user.setLastName(screen.getLastName());
Sembra buono, non proprio ridondante, almeno non in un modo che puoi risolvere, giusto? Ma ti fa aggiungere una linea quando vuoi aggiungere un "secondo nome", quindi è "codice ridondante"
user.getNameAttributesFrom(screen);
Non ha bisogno di un nuovo codice per questa attività - richiede semplicemente che alcuni attributi in "schermo" siano contrassegnati con un attributo "Nome", ma ora non possiamo copiare l'indirizzo, come su questo:
user.getAttributesFrom(screen, NAME_FIELDS, ADDRESS_FIELDS);
Più bello, un var-args ti permette di includere un gruppo di attributi (da un enum) per raccogliere dallo schermo - ancora devi modificare il codice per modificare i tipi di attributi che vuoi. Nota che "NAME_FIELDS" è una semplice istanza di enum - i campi in "schermo" sono etichettati con questo enum quando sono progettati per inserirli nelle categorie corrette - non esiste una tabella di conversione.
Attribute[] attrs=new Attributes[]{NAME_FIELDS, ADDRESS_FIELDS, FRIENDS_FIELDS};
user.getAttributesFrom(screen, attrs);
Ora hai capito dove stai solo cambiando "Dati". Questo è dove di solito lo lascio - con i dati nel codice - perché è "abbastanza buono". Il passo successivo consiste nell'esternalizzare i dati, se necessario, in modo da poterli leggere da un file di testo, ma raramente lo è. I refactoring "Roll up" sono molto simili una volta che hai preso l'abitudine, e quello che ho appena fatto lì ... ha creato un nuovo enum e pattern che finirà per scorrere in molti altri refactoring.
Infine, si noti che le buone soluzioni generiche per problemi come questo NON sono dipendenti dalla lingua. Ho implementato una soluzione no-code-per-loc per analizzare una GUI di testo dalla riga di comando di un router, aggiornandola sullo schermo e scriverla sul dispositivo - in VB 3. Ci vuole solo la dedica al principio di non scrivere codice ridondante, mai, anche se devi scrivere il doppio del codice per farlo!
Anche l'interfaccia pulita (completamente Factored e non consente il passaggio di materiale illegale) è importante. Quando si calcola correttamente un'interfaccia tra due unità di codice, è possibile manipolare il codice su entrambi i lati dell'interfaccia con impunità e consentire ai nuovi utenti di implementare in modo pulito le interfacce.