lunedì 29 dicembre 2014

Oggetti Builder

Vediamo oggi brevemente un'altra tecnica per la creazione di oggetti in Java: i Builder.

Abbiamo già visto nell'articolo precedente come in linguaggi C-like come Java manchino i nomi nei parametri passati nelle chiamate.
Questo diventa un problema nella leggibilità del codice soprattutto nei costruttori, dove oltretutto siamo obbligati a specificare soltanto un nome di metodo uguale al nome della classe.
I metodi factory presentati la volta scorsa non risolvono il problema dei nomi dei parametri e con il crescere del numero di parametri da passare, la difficoltà di comprensione e lettura del codice può solo peggiorare.
Il Builder Pattern risolve questo problema definendo una classe la quale mantiene internamente i parametri sia obbligatori che facoltativi che saranno da passare poi al costruttore vero della classe per la quale si desidera creare un'istanza.

La classe Builder deve avere dei metodi con un nome significativo per ciascun parametro da passare.
Un metodo "build" della classe builder stanzia la classe, passando i parametri valorizzati con i metodi dei quali scrivevo prima.

Si potrebbe obiettare che è sufficiente chiamare un costruttore senza parametri e poi usare dei metodi setter per passare i parametri. Purtroppo però questo presenta un altro svantaggio: usando i metodi setter non c'è un unico punto dove si può fare la validazione, cioè se diversi parametri devono concorrere per un criterio, che stabilisca la validità della creazione di un oggetto, è quasi impossibile verificare tale criterio, se i parametri sono passati con diversi metodi "set".

Il builder con il metodo "build" può concentrare il processo di validazione in un unico punto.

Inoltre JavaBeans, suggerendo di usare dei metodi setter, rende impossibile creare una classe immutabile, che oggi più che mai è importante, visto che l'hardware con il processori multi core a basso costo permette sempre di più di avere programmi con parti che girano in parallelo.

In Java l'abstract factory è realizzato dal metodo newInstance dell'oggetto Class. Purtroppo però newInstance chiama un costruttore senza parametri, con le limitazioni già discusse.

Anche per questi consigli e per vedere un esempio, si faccia riferimento all'ottimo Effective Java di Joshua Bloch.

A differenza di Bloch però, mi permetto di notare che è meglio non ricorrere a classi Builder statiche, proprio per potere usare i builder anche in ambienti multi thread, dove le parti statiche sono una fonte di problemi...

lunedì 22 dicembre 2014

Creazione di oggetti

A differenza di Objective-C o di alcuni linguaggi per stored procedure dove si passano anche i nomi dei campi oltre ai loro valori, purtroppo nei linguaggi C like come Java, conta solo l'ordine e il tipo dei parametri passati.
Questo rende le chiamate dei metodi più corte, ma meno leggibili con il crescere del numero dei campi da passare.
Un altro problema è dato dal fatto che i costruttori in Java hanno il nome della classe, quindi non comunicano molto al lettore (programmatore) della propria specificità: cioè dal nome si capisce che si tratta di un costruttore, ma non si sa altro.

Per ovviare a queste limitazioni vengono in aiuto alcuni "trucchi", alcuni presi più o meno direttamente dai pattern descritti dalla Gang of Four, altri invece sono adattamenti.

Il modo più semplice per ovviare alla chiamata diretta di un costruttore è ricorrere ad un metodo Static Factory, come ad esempio:
public static Boolean valueOf(boolean b) {
  return b ? Boolean.TRUE : Boolean.FALSE;
}

I vantaggi dei Metodi Static Factory sono:

  1. Un metodo Static Factory ha un nome preciso a differenza di un costruttore, quindi comunica di più a chi lo legge.
  2. Uno static Factory non deve necessariamente creare un oggetto nuovo per ogni chiamata, potrebbe infatti richiamare delle istanze pre costruite oppure chiamare un istanza con un insieme di valori particolari a seconda di quale factory pattern è richiamato.
  3. Uno static Factory può restituire un oggetto di un sottotipo rispetto alla classe dell'oggetto chiamato, cosa impossibile per un costruttore e questo crea una grande flessibilità
  4. Semplificano la creazione di istanze di tipo parametrico, come ad esempio HashMap.newInstance() che ritorna un oggetto parametrico come specificato nella parte sinistra dell'assegnazione. C'è da dire che in effetti questo vantaggio oggi è reso ininfluente dall'esistenza del diamond <>, comparso con Java 7


Ci sono anche un paio di svantaggi, anche se a mio avviso sono poca cosa rispetto ai vantaggi:

  1. Una sottoclasse istanziabile da un metodo static factory deve avere dei costruttori pubblici, invece non si possono chiamare costruttori privati o protected.
  2. JavaDoc non distingue i metodi static factory dagli altri metodi static, quindi non è sempre immediato capire se un certo metodo statico costruisce istanze o se fa altro.


Queste informazioni sono tratte dal libro: Effective Java di Joshua Bloch

domenica 14 dicembre 2014

Il pesce puzza dalla testa

In un progetto è fondamentale il ruolo di chi ha l'ultima parola.

Il ruolo del capo è sempre assegnato. Nessuno ha il potere per volere divino, ma perché chi possiede il denaro comanda o più spesso delega il comando a una persona di fiducia.
La fiducia di chi possiede il denaro non è garanzia di qualità del leader. E' soltanto un atto burocratico, spesso non meritocratico.
Non c'è niente di peggio di un capo inadeguato che ha potere di veto sulle proposte degli altri membri del team e che impone una linea sbagliata.
Per linea sbagliata intendo diverse cose, non necessariamente una strategia che non può portare al risultato, quanto un atteggiamento che non tiene conto delle persone interessate al progetto, non tiene conto delle loro competenze ed esperienze, come del loro carattere.
Le persone coinvolte in un progetto sono i tecnici, ma anche e soprattutto le persone che commissionano un progetto o che lo usano.
Un progetto software è un'entità che coinvolge diverse persone con ruoli diversi e un buon capo dovrebbe tenere conto di tutti, quindi diventa importante sviluppare un nucleo di funzioni (che è l'unico obiettivo dei manager della vecchia scuola), ma anche studiare l'interfaccia utente e in generale l'usabilità dell'applicazione (Apple insegna), così come documentare per ciascun caso d'uso cosa può entrare nella procedura e cosa deve uscire, documentare i limiti e gli intervalli di validità dei dati di ingresso, come documentare cosa dovrebbero fare gli utenti nei diversi casi d'uso.
Un buon team leader deve tenere conto di tutti questi aspetti, che hanno la stessa dignità e importanza.
Un progetto ben fatto rimane soltanto un potenziale inespresso fino a quando gli utenti non diventano in grado di usarlo. Cioè rimane un sacco di soldi spesi che non portano frutto.
Ecco che il ruolo del formatore e dell'account manager assumono importanza fondamentale, la stessa importanza che hanno i tecnici realizzatori del progetto.
Fino a quando i capi progetto avranno soltanto una formazione tecnica o manageriale e nessuna esperienza nel campo della comprensione delle persone, continueremo a vedere progetti naufragare nonostante la tecnologia e la preparazione.

E' una dimostrazione di maturità, oltre che di umiltà, sapere ascoltare.

I migliori capi giudicano poco e riprendono poco, perché prima che la gente agisca,  essi hanno comunicato con chiarezza cosa va fatto.
Purtroppo molto spesso una volta raggiunta una posizione alta, il capo si sente arrivato e comincia a trattare con sufficienza i membri del team o i clienti, come se questi fossero tutti meno preparati o con capacità cognitive inferiori. Il risultato è spesso una serie di incomprensioni e di acredini.
La cosa che tutt'oggi mi sorprende è come chi investe soldi nel progetto, spesso non ponga obiettivi intermedi o almeno criteri di valutazione per capire se chi comanda, ha le qualità tecniche, ma soprattutto umane per dirigere un lavoro nel modo migliore e si aspetti la fine del progetto per giudicare tutto il team, come se fosse un giorno del Giudizio Universale, dove chi paga è un dio cieco e sordo, che si è svegliato dal torpore, per capire all'ultimo momento che chi comandava, non era adatto a quel ruolo.

lunedì 8 dicembre 2014

Oggetti immutabili

Anni fa, secoli in termini informatici, esisteva il BASIC.
Il BASIC aveva un comando assai comodo: il GOTO che faceva saltare l'esecuzione del programma in un altro punto. Chiunque avesse studiato l'Assembly era abituato alle istruzione di Jump e non si vedeva niente di strano a fare salti con il GOTO.
L'abuso del GOTO portava a programmi per i quali era quasi impossibile seguire chiaramente il flusso di esecuzione del codice e si coniò un termine per quello stile di programmazione : "Spaghetti Code" per via del  groviglio che assumeva il flusso delle istruzioni, che in condizioni ideali, dovrebbe essere il più lineare possibile, per facilitare la leggibilità e la comprensione del programma.

Divenne comunemente accettato nella pratica della programmazione bandire il GOTO e "condannare" chi ne faceva uso come cattivo programmatore.
Più volte nella storia della programmazione si è considerata cattiva pratica qualcosa che fino a prima sembrava la cosa più normale del mondo.
Sono stati oggetto di ostracismo le stored procedure, la programmazione procedurale, la programmazione non cross platform ecc...

Oggi la diffusione sempre maggiore di macchine con ottime capacità di lavoro in parallelo e a basso costo, ha costretto a riconsiderare alcune pratiche di programmazione, che creano problemi in questi nuovi scenari.
Poter cambiare i valori delle proprietà di un oggetto in un contesto multithread, per esempio, è pericoloso perché ci espone al rischio che ci sia un accesso concorrente di più thread alla stessa risorsa, con blocchi o risultati difficilmente prevedibili.

Una delle strategie più recenti per difendersi da questi problemi, è semplicemente rendere gli oggetti immutabili, cioè non si deve permettere la modifica di un oggetto dopo la sua creazione e bisogna ricorrere alla creazione di un oggetto nuovo con i nuovi valori, che andrà a sostituire il vecchio.

Di sicuro non è un approccio che favorisce le prestazioni, però in effetti bisogna ammettere che evitare i rischi del multithreading è allettante.

Detto questo, ci sono casi nei quali un oggetto immutabile è semplicemente impossibile, per esempio una maschera dove i bottoni sono abilitati o disabilitati a seconda dello stato dell'applicazione, mi sembra la dimostrazione che in pratica un approccio così totalizzante, come evitare SEMPRE le classi mutabili, non sia possibile.

Un altro possibile approccio è quello usato dagli application server Java, dove la specifica proibisce ai programmatori delle web app di usare i thread, perché l'application server fornisce gli strumenti per far girare il codice in parallelo, senza ricorrere direttamente ai thread.

E' senza dubbio un'altra strategia difensiva, purtroppo però non è pensabile che ci sia sempre un application server sotto alla nostra applicazione, quindi non è una ricetta universale.

domenica 30 novembre 2014

L'azienda NON è una scuola

In azienda non si studia. In azienda si deve produrre, l'azienda vive di denaro.
Questa visione, che è comune alla maggior parte delle aziende piccole e medie italiane, produce come risultato che noi oggi usiamo la tecnologia del martinetto, quando le aziende del nord Europa sono alla tecnologia del chip.

E' colpa dei cattivoni nordici che usano l'euro a loro vantaggio se non siamo competivi?
No, è colpa nostra che produciamo roba vecchia, che i cinesi possono copiare senza troppi problemi.

Non sto dicendo che l'azienda debba sostituirsi alla scuola. Perlomeno non alla scuola che conosciamo tutti, "orribile e inutile" (Sant'Agostino)

La scuola addestra all'autorità, ai voti, all'ansia, all'astuzia e alla sudditanza. (I. Sibaldi)

L'azienda deve insegnare in modo fortemente pragmatico cosa offre il mondo moderno e come mettere in relazione le informazioni.

Si pensi a una società di informatica dove non si aggiorna il personale, il quale deve studiare da solo di sera, se vuole e se può. Col tempo le persone che avanzano di carriera per anzianità avranno conoscenze vecchie rispetto ai nuovi assunti e li comanderanno, male e riempiendoli di frustrazioni.

Ora, un software comandato da chi aveva un approccio alla programmazione completamente diverso e vecchio rispetto alle tecnologie attuali, che probabilità ha di usarle nel modo giusto?

Questa è la seconda ragione dietro al fallimento di molti progetti.
Il primo è l'incapacità di capirsi

domenica 23 novembre 2014

Quando non basta un'ascia ben affilata

Se avessi a disposizione otto ore per abbattere un albero, ne passerei sei ad affilare l’ascia (A. Lincoln)

Molti anni fa, mi fu offerto di rifare completamente un gestionale interno per un'azienda delle mie parti. Avrei avuto la possibilità di scegliere io gli strumenti o quantomeno di influenzarne pesantemente la scelta.

Ero eccitatissimo all'idea, per una sfida che ero sicuro di centrare, sarebbe stato, pensavo, un successo, finalmente la possibilità di fare qualcosa di grande e di fare il salto di qualità che cercavo.

Per una missione così importante, pensai bene che gli strumenti che avevo usato fino a quel momento non fossero indicati e ancor oggi credo che questo fosse giusto.

Mi informai presso degli amici che lavoravano in città di quale database avessi potuto dotarmi per quell'impresa, senza legarmi a un particolare sistema operativo, perché già allora mi ero avvicinato a Linux e all'open source. Inoltre avevo già studiato i primi rudimenti di Java e di programmazione a oggetti e mi sentivo quasi pronto.

Mi fu consigliato DB2 UDB versione 5 di IBM. Come IDE pensai a Jbuilder 3 Enterprise dell'allora Borland. Avevo a disposizione il budget e degli strumenti di classe enterprise, tutto ciò che avevo chiesto l'avevo ottenuto.

Fu una catastrofe.

Una lezione che imparai col tempo è che una lenta evoluzione è sempre preferibile a una sanguinosa rivoluzione e che quando è proprio necessario buttare via uno strumento intero, si tratta di una situazione veramente grave per chi ha fatto le scelte precedenti. Spesso poi chi fa la nuova versione si trova nel bivio se portare avanti anche i bug o quantomeno i comportamenti sbagliati del programma precedente o se cambiare strada, anziché fare "semplicemente" un porting come previsto.

JBuilder 3 era una cozzaglia di bug, indegno del nome dell'azienda che lo aveva creato e che  aveva una forte tradizione negli ambienti di sviluppo. Le versioni successive erano migliori, ma chi era rimasto scottato da quell'esperienza aveva probabilmente messo una croce sul nome Borland, che dopo pochi anni, guarda caso, cedette gli strumenti di sviluppo ad altri.

Il mio errore? Non averlo provato a sufficienza senza dubbio fu uno sbaglio di inesperienza, ma l'errore più grave fu non chiedere prima al cliente, con una demo magari, se i controlli presenti nell'IDE e completamente proprietari di Borland, avevano un comportamento accettabile per lui e cos'altro avrebbe desiderato.

Fu un'errore che mi costrinse in corso d'opera a cambiare completamente il framework, per SWING. Chiunque abbia sviluppato con SWING sa di cosa parlo...

DB2 era il database di una multinazionale che aveva fatto la sua fortuna sui progetti di gestione dei dati. Aveva funzionalità avanzatissime quali la possibilità di gestire le dimensioni dei pool di pagine del disco, ripartizione delle tabelle, gestiva query lunghe diverse pagine senza problemi, gestiva partizioni sul disco proprietarie saltando il sistema operativo E NON PERMETTEVA DI CANCELLARE UNA COLONNA.
Mi sembrava incredibile, ma bisognava esportare i dati, togliere le integrità referenziali, cancellare la tabella e reimportare i dati senza la colonna, poi ricreare le integrità ecc...
Il cliente era tra il furibondo e lo scoraggiato. Io non riuscivo a darmi una spiegazione ed ero mortificato. Seppi poi che la versione per AIX (io usavo quella per windows NT) non soffriva di questo problema. Una mossa "commerciale" di IBM per penalizzare l'uso di proprio prodotti sulle piattaforme concorrenti? Una sorta di castrazione insomma...

Si trattava di uno strumento rigidissimo, sviluppatosi in contesti dove le specifiche sono scritte nel marmo, mentre una piccola impresa invece vive d'agilità.
Aveva anche dei bug sottili, come il fatto che quando si faceva un restore su una macchina diversa con partizioni gestite direttamente, la nuova partizione doveva essere un pelino più grande, altrimenti il restore non funzionava. Inoltre c'erano altri piccoli comportamenti fuori standard con Java che lo rendevano imprevedibile, fino a quando non si sapeva che fare.

Se avessi fatto un programma più piccolo ma completo prima, forse avrei parato molti colpi, ma il problema principale fu che uno strumento così difficile ha senso soltanto per chi ha contratti di supporto e fa corsi o è inserito in una cerchia di consulenti che lo conosce, magari legati al produttore. La mia ignoranza su DB2 la pagai con il dovere risolvere in fretta problemi sul campo e quel progetto mi fece invecchiare presto. Ancora più grave fu il rapporto di fiducia irrimediabilmente incrinato con chi si aspettava che sarebbe stata una passeggiata e aveva pagato profumatamente quegli strumenti.

DB2 era su un livello qualitativo ben superiore all'IDE che avevo scelto, ma in quell'ambiente e con la mia inesperienza, non era proponibile.
L'aggiunta di problemi con gli strumenti è una vera condanna per un progetto, perché oltre ad avere tempi lunghi, agli occhi dei clienti la colpa ricade sulle nostre capacità.

La paura, madre di ogni freno, fa si che molti scelgano di usare strumenti vecchissimi (si vede ancora in giro del vecchio Visual Basic 6) con la conseguenza che dopo un po'... il nostro software non gira più sui nuovi sistemi... miracoli del consumismo tecnologico.

Soltanto una perfetta padronanza degli strumenti assicura di potersi concentrare sulle esigenze (e sulle convinzioni) dei clienti, i quali prima di tutto devono potersi fidare di noi.

Credo che oggi non rifarei gli stessi errori. (!)

lunedì 17 novembre 2014

Insicurezza e senso pratico

Tempo fa feci notare a un programmatore freelance, che avrei preferito che sviluppassimo il database usando chiavi esterne con campi singoli interi, perché erano più comodi.
Il tipo trasalì. Diventò tutto rosso e mi rispose che TUTTI USANO LE CHIAVI MULTIPLE.
Sbagliando, lo lasciai fare.
Tempo fa si usavano le chiavi multiple, perché c'era scritto sul libro, perché lo spazio sui dischi era costoso e si risparmiava un campo in più, oppure il db non offriva le sequenze o contatori, quasi indispensabili quando si usa una chiave singola, oppure per motivi di fede in qualcosa che avevano sempre visto fare.

Onestamente, quando si affrontano problemi come la sincronizzazione dei dati su altre macchine, l'approccio tradizionale ha i suoi vantaggi e le sequence/campi contatore/campi identità diventano un problema.

In quell'applicazione le chiavi multiple erano soltanto una complicazione inutile.
Quel collega si sentiva protetto dalle abitudini. Da ciò che aveva sempre visto fare. Era insomma diventato schiavo della sua insicurezza, che placava ricorrendo alle stesse soluzioni.

In un'altra occasione mi trovai a discutere con due programmatori esperti, uno sosteneva che Hibernate fosse la soluzione ai tempi di sviluppo troppo alti che avevano afflitto il loro progetto, l'altro guardava sospirando la semplicità delle procedure Oracle. E' la vecchia diatriba tra se sia meglio tenere la logica nel middleware a oggetti o nelle stored procedure. Non ho mai sentito loro pronunciare le parole"dipende dal problema che si vuole risolvere".

I due erano degli eccellenti tecnici, ma avevano perso di vista che quello che facciamo è risolvere problemi. Fare progetti usando una tecnica sola e imporre quella come se fosse la via illuminata verso il successo è come pretendere di smontare un'automobile usando una sola chiave inglese.
Anche se in teoria forse è fattibile, qualsiasi meccanico si metterebbe a ridere di fronte a una simile proposta e probabilmente prenderebbe per matto chi si accapigliasse per sostenere questa tesi.

Per quanto mi riguarda, posso dire che io mi trovo molto più a mio agio a usare gli oggetti nel middleware, posto che questo non comporti la generazione inutile di migliaia di oggetti in memoria, però spesso ho risolto problemi di performance sfruttando il database, visto che spesso oggi le soluzioni dentro al database sono fatte in linguaggi portabili tra database diversi e sistemi operativi diversi.

Mi sembra un dato di fatto che il database debba essere sempre coerente e che quindi le regole di validità sui dati e l'integrità referenziale debba esserci, anche quando si usa prevalentemente il middleware, questo perché in futuro altre applicazioni potrebbero accedere al db e non vedrei il senso di moltiplicare le regole, replicandole nei vari strati.
Capisco meno magari chi si rifiuta di fare una semplice query dinamica per paura che sia lenta, dal momento che la preparazione del piano di esecuzione oggi spesso è in cache.

Io personalmente la vedo così: le query dinamiche hanno senso in contesti dinamici, quindi quando la query si costruisce dinamicamente cambiando volta per volta quali campi o filtri sono coinvolti. Credo che rinnegare un database relazionale maturo e magari costoso non abbia senso, in quanto non ha senso spendere fino al punto di rischiare un fallimento per risolvere problemi che non si hanno. Questo può sembrare un controsenso perché a tutti viene insegnato di prepararsi (per non dire addirittura preoccuparsi, altro errore) per il futuro.
Eppure viviamo nel presente. Sembra strano ma roviniamo il presente che è certo per il futuro che è incerto.
Io stesso ho fatto procedure enormi con strati che ripetevano le stesse cose per ciascun strato: un controllo javascript sulla pagina html, poi lo stesso controllo nel middleware, poi altri controlli nel db. Questo si traduce in COSTO. Un costo per una qualità non sempre richiesta.

Credo che non tutte le applicazioni abbiano bisogno di essere strutturate come il sistema informativo di una banca, così come non tutte le persone sono disponibili a pagare auto di lusso pluriaccessoriate e sono felici di usare delle utilitarie a un costo che è una frazione. Questo non vuol dire non fare lavori di qualità, vuol dire fare lavori nei costi che chi paga è disponibile ad accettare.

Chi non capisce questo e segue la strada maestra indicata nei forum e nei libri, per sentirsi sicuro di avere fatto il lavoro a regola d'arte e tutelarsi dalle critiche future dei colleghi, dalle contestazioni dei clienti e dalle future richieste di modifiche stravolgenti, è soltanto un insicuro, perché la gente è libera di criticare in base al pensiero del momento, perché il cliente si accorge di cosa vuole quando in effetti mette le mani sulla programma, perché cosa ci accadrà è stimabile, ma imprevedibile. E' la vita.








Programmazione Orientata agli Stipendi

Anni fa due miei giovani colleghi mi dissero che EJB era nato per fare un modello a oggetti, partendo da un modello relazionale.
Già allora la loro convinzione mi lasciava perplesso.
Credo che EJB sia nato per favorire il passaggio delle procedure COBOL verso Java. Banche e assicurazioni usavano COBOL e erano i clienti pronti a pagare. L'ecosistema Java è stato guidato dal business, non da chi scrive pattern.
EJB non è OOP, non perché chi lo ha scritto non fosse abbastanza bravo, ma perché è stato fatto per essere orientato ai servizi, come richiesto dai clienti pronti a pagare i ricchi middleware EJB.
Non lavoriamo in un mondo ideale sul piano tecnico scientifico, lavoriamo perché qualcuno ci paga o speriamo proprio che lo faccia.

mercoledì 10 settembre 2014

MVC non sempre

Dopo un lungo periodo di inattività, dovuto ai miei impegni lavorativi, oggi mi sono imbattuto in un articolo un po' datato, ma ancora attuale, che ha attirato la mia attenzione e che mi ha generato qualche riflessione.
L'articolo in questione si trova su: http://www.javaworld.com/article/2076459/core-javauilding-user-interfaces-for-object-orient/core-java/building-user-interfaces-for-object-oriented-systems--part-1.html

In effetti, MVC apparentemente è in contrasto con l'approccio Object Oriented puro. Ma credo che sia il caso di approcciare il problema senza troppi aut aut, invece dovremmo considerare il sistema nel suo complesso per capire.

Riutilizzare il codice è il motivo principale che ha portato alla OOP. Nel caso dei componenti grafici (widget) per l'interfaccia utente, avere oggetti che non sanno nulla del dato da rappresentare è cosa ottima, nonché in pratica assolutamente necessaria. Anche avere degli oggetti nel modello che comunicano le modifiche tramite eventi è cosa buona per riutilizzare e separare il codice.

Fino a questo punto sembra che MVC sia sempre la cosa giusta, tuttavia nella pratica di tutti i giorni si assiste a un suo uso, dovuto soprattutto al massiccio impiego degli strumenti di sviluppo rapido (RAD), che ne stravolge il senso.

Se ci sono, per esempio, diversi punti nell'interfaccia utente che riguardano una certa proprietà di un oggetto, per esempio il nome di una persona, la quale si ritrova in diverse maschere o report, il giorno nel quale si decida di fare una modifica per aggiungere il titolo (sig. dott. sig.ra ecc) lo si dovrà fare in tutti i punti del codice della gui. Questo è assurdo rispetto ai principi della OOP, che vuole facilitare il riutilizzo!

I RAD sono strumenti nati per fare prototipi, non per fare codice di produzione, purtroppo l'elevato costo iniziale dello sviluppo ha promosso i RAD anche dove sarebbe stato meglio che non fossero utilizzati. L'uso scriteriato di MVC porta a dovere modificare il codice in più punti, a meno che non si creino degli oggetti lato View che si conoscano in qualche modo il dato, oppure oggetti fintamente generici, ma che in pratica si useranno solo per quel dati,  ma si viene a perdere la separazione reale tra modello e view.

La soluzione? Usare MVC solo quando e dove serve, cioè all'interno degli oggetti wrapper, in modo che gli oggetti sappiano come rappresentarsi e magari come salvarsi !

Agli occhi di molti fedeli dei manuali di pattern, questo può sembrare un'eresia, ma non lo è.
Avere un'oggetto, anzi, avere un'interfaccia che propone i metodi per rappresentare un oggetto o per salvarlo, è proprio cioè che la OOP all'inizio si prefiggeva di fare!
I dettagli su come questo accada sono nascosti (incapsulati) dentro all'implementazione e questo deve essere trasparente a chi chiama (passa messaggi) a tali oggetti.

Per evitare che l'oggetto in questione diventi enorme e impossibile da mantenere, nessuno ci impedisce di ricorrere a delle strutture a plugin affinché l'oggetto implementante chiami altri oggetti per produrre diverse interfacce utente (Swing, HTML, Android ecc...) o per salvarsi su database con dialetti diversi.

Per esempio un campo "nome" che si mappa su un JTextEdit potrebbe internamente instanziare un JTextEdit e collegarsi ai suoi eventi. In questo modo non è più necessario per il programmatore o per l'IDE realizzare tale legame per ogni volta che questo oggetto è usato.
Se si desidera creare una web application, il campo "nome" potrebbe generare il codice html con tanto di controllo client - side!
Con un file di configurazione si potrebbe definire quali plugin i nostri oggetti dovrebbero caricare, per  generare le due GUI così diverse.
Se definiamo un metodo "disegna" nell'interfaccia del nostro oggetto, potremmo passare un generico oggetto "Contenitore" che sarà un JPanel o un body html.

Si potrebbe obbiettare che in questo modo la definizione dell'interfaccia diventa difficile, tuttavia mi viene in mente l'esempio dei css nel mondo html, dove il posizionamento, il colore, i bordi ecc sono definiti all'esterno. Credo che anche in questo caso tali regole grafiche per le interfacce potrebbero trovarsi all'esterno dell'oggetto e che magari potrebbero essere generate scrivendo del codice, così come scrivendo i css direttamente.

In questo modo la logica del programma non vede il controller e non vede i dettagli della gui e può veramente riutilizzare gli oggetti, incapsulando i dettagli. Questo è compatibile con un RAD? Direi di no, ma sono certo che i tempi di sviluppo, soprattutto per quanto riguarda la manutenzione, si abbatterebbero in questo modo.
Il discorso cambia nel caso di fast prototyping, dove i RAD rimangono secondo me strumenti molto efficaci.