Visualizzazione post con etichetta pattern. Mostra tutti i post
Visualizzazione post con etichetta pattern. Mostra tutti i post

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

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.