Perche' potresti trovare delle soluzioni gia' pronte a problemi che ti si sono presentati in passato e che incontrerai daccapo nel futuro.Inoltre ormai il gergo degli specialisti e' pieno a proposito o sproposito di termini che vengono dai design pattern: se volete capire gli specialisti oppure "fare finta di essere " uno di loro dovete parlare di Abstract Factory, Proxy, etc cosi' come parlate di ereditarieta' e polimorfismo.
Cosa sono i Design Patterns?
Quando si e' cominciato a lavorare seriamente con i linguaggi ad oggetto, la gente si e' resa conto che si presentavano ad ogni programma, dei problemi ricorrenti.Un gruppo di 4 programmatori (la banda dei 4, GoF(Gang of Four) ha cercato di formulare una lista dei 23 problemi piu ricorrenti (e delle loro soluzioni) e cosi' nel 1994 sono nati i Design Patterns.
Perche' sono stati chiamati Design Patterns?
L'idea era di andare oltre il riuso degli oggetti : di riuscire a far riusare il disegno degli oggetti creato per risolvere problemi ricorrenti: i design pattern.
Cos'e' cambiato da allora
L'idea ha avuto tanto successo che sia C++ che Java hanno incluso alcuni di questi pattern tra le loro caratteristiche. Ad esempio Iterator che ormai e' di uso comune per esaminare gli oggetti di un contenitore STL o Java , indipendentemente da come e' fatta l'implementazione dello stesso.
Perche' questi problemi sono sorti solo con la programmazione ad oggetti?
La programmazione ad oggetti puo' essere anche piu' ad alto livello di quella procedurale, ma ci si e' resi conto subito che e' difficile non tanto perche' sia difficile scrivere dei "buoni" oggetti, quanto perche' la comunicazione tra gli oggetti puo' creare delle situazioni complicate e nuove rispetto alla programmazione procedurale.
Puoi fare qualche esempio?
Ad esempio, nella programmazione procedurale, voi definite delle variabili globali e tutte le funzioni possono accedervi.Nella programmazione ad oggetti queste vanno incapsulate in una classe ed e' questa che deve essere accessibile da parte di tutti gli altri oggetti che vogliono accedere/modificare queste variabili globali. Questo e' un problema ricorrente chiamato dalla GoF Singleton.
Come fa il design pattern Singleton a risolvere questo problema?
Si crea una classe che ha come attributo statico privato se stessa e si auto instanzia nel costruttore (anch'esso privato). Per accedere alla classe e quindi alle variabili
da essa incapsulate, esiste un metodo getistanza()
che ritorna il suo indirizzo.
Ecco il codice in Java e C++.
Qualche altro esempio concreto
Il pattern Factory risolve il problema di instanziare oggetti che ereditano dalla stessa classe con un'unica istruzione, anche se gli oggetti possono avere costruttori diversi. Qui un esempio di implementazione in C++
Quali sono i 23 Pattern canonici?
Abstract Factory,Adapter,Bridge,Builder,Chain of Responsability,Command,Composite, Decorator, Facade, Factory Method, Flyweight, Interpreter, Iterator, Mediator, Memento, Observer, Prototype, Proxy, Singleton, State, Strategy, Template Method, Visitor.
Oltre ai 23 Pattern canonici, ce ne sono altri?
Si,in ogni caso quella lista era solo una prima
esemplificazione di un nuovo metodo di programmare e non una lista definitiva.
Un pattern famoso (nato ancora prima del 1995 con SmallTalk) e' MVC (Model, View, Controller) usato dappertutto nelle applicazioni grafiche.(Prima che i pattern fossero di moda, MVC era indicato come un paradigma o framework o architettura
di software).
Potete trovare in questo sito una definizione dettagliata di software patterns e in generale
una descrizione della filosofia che sta dietro i pattern .
A quale problema si riferisce il pattern Observer e come mai e' cosi' spesso citato?
L'Observer risolve il problema della cosiddetta programmazione guidata dagli eventi, in cui un evento generato da un particolare oggetto , deve essere prontamente notificato a una serie di oggetti (appunto gli observer) che devono ognuno rispondere in qualche modo all'evento.Un'altra maniera di definirlo e' di dire che si crea una dipendenza tra un singolo oggetto monitorato e altri n oggetti interessati ad essere informati quando l'oggetto monitorato cambia stato.
Questo pattern ricorda moltissimo la gestione degli eventi in Java
Che infatti risolve lo stesso problema.
E il meccanismo slot/signal in Qt
Un'altra soluzione dello stesso problema.
Che relazione c'e' tra Observer e MVC?
Il pattern Observer risolve il problema in MVC delle multiple viste di un unico modello descritto da certi dati: ad esempio una rappresentazione grafica e una come testo.Quando i dati cambiano, le due viste devono saperlo per modificare se stesse.
Che significano con esattezza le parole Observable,Observer,Dispatcher, Event,Callbacks,...
In effetti il problema risolto dal pattern Observer si presenta cosi' di frequente da aver generato tutto un gergo che bisogna capire prima di vedere la soluzione.
update
che viene richiamato all'atto della notifica.Invece
l'oggetto Observable deve essere ereditato dall'oggetto osservato.Questo puo'
allora richiamare il metodo notifyObservers()
quando vuole notificare gli Observer.
Quando l'oggetto osservato s viene creato ogni observer o si deve registrare
richiamando s.addObserver(o).
Come faccio a implementare Observer in C++ dove non ho classi Event, Listener, Observer e Observable?
Bisogna distinguere 2 casi: uno piu' semplice in cui vogliamo trattare un unico
tipo di evento.Allora l'oggetto che genera l'evento deve ereditare una
classe Observable che ha un set STL per memorizzare gli observer
e una serie di metodi addObserver()
deleteObserver
etc oltre al metodo notifyObservers()
che esamina il set e richiama
il metodo update()
di ogni Observer registrato.
Invece gli oggetti Observer basta che implementino il metodo update()
definito in una classe astratta Observer.
E se vogliamo implementare piu' eventi?
Allora la cosa si complica di parecchio:una soluzione possibile e' quella
proposta in Thinking in C++ che consiste nel definire per ogni Observable i diversi eventi che puo'
generare con differenti inner class (simili ai listener Java). Allo stesso modo ogni
Observer di piu' eventi deve avere tante inner classi InnerObserver
quanti sono gli eventi. Una volta istanziato l'oggetto Observable, tutti
gli Observer interessati agli eventi dell'oggetto registrano le proprie
inner class richiamando addObserver
della inner class corrispondente all'evento. Insomma una cosa abbastanza complicata.
Se vuoi vedere la lista completa dei 23 pattern canonici implementati in Java GoF's Design Patterns in Java
JavaWorld parla molto spesso di design pattern in Java: basta cercare "design pattern" nel sito.
Event Notifier, a Pattern for Event Notification