Archivio per marzo 2010

Post

Template Method

In Design Patterns on marzo 28, 2010 di poyblog Messo il tag: ,

Intento:

Definisce lo scheletro di una algoritmo in una operazione e delega alcuni passaggi alle sottoclassi. Il pattern Template Method lascia alle sottoclassi la possibilità di ridefinire certi passaggi di un algoritmo senza cambiarne la struttura.

Applicabilità:

Il pattern in questione è da sfruttare nei seguenti casi:

  • per implementare le parti non variabili di un algoritmo una sola volta e lasciare alle sottoclassi la responsabilità di implementare i comportamenti che possono variare.
  • Quando il comportamento delle sottoclassi può essere fattorizzato e localizzato all’interno di una unica classe senza ripetizioni di codice (esempio di refactoring del tipo “refactoring to generalize”)
  • nel caso in cui si voglia controllare l’estensione delle sottoclassi. Si può creare un template che crea degli hook (letteralmente uncini o ganci) che possono essere utilizzati per permettere estensioni, solo dall’hook in poi.

Partecipanti:

  • AbstractClass → definisce operazioni primitive che le sottoclassi definiscono per implementare gli step dell’algoritmo; definisce anche un metodo template per definire l’ossatura dell’algoritmo.
  • ConcreteClass → implementa le operazioni primitive per fornire i passaggi dell’algoritmo secondo la specifica sottoclasse

Conseguenze:

L’utilizzo del pattern Template Method è una tecnica fondamentale per il riutilizzo del codice, in particolare per le librerie.

Il Pattern in questione chiama diversi tipi di operazioni, fra le quali:

  • operazioni concrete a livello di ConcreteClass
  • operazioni concrete a livello di AbstractClass
  • operazioni primitive
  • Factory Method
  • operazioni hook le quali forniscono comportamenti di default che possono essere estesi dalle sottoclassi se necessario.

E’ molto importante per il pattern specificare quali operazioni possono essere sovra-scritte (hook) e quali devono essere sovra-scritte (operazioni astratte)

Post

Strategy

In Design Patterns on marzo 28, 2010 di poyblog Messo il tag: ,

Intento:

Definire una famiglia di algoritmi, incapsularli tutti e renderli intercambiabili. Il pattern Startegy infatti lascia che gli algoritmi possano variare in base a chi e come li richiama.

Applicabilità:

Il pattern è da utilizzare quando:

  • ci sono molte classi relazionate che differiscono solo per il loro comportamento. Strategy fornisce un metodo per configurare una classe con uno dei tanti comportamenti.
  • C’è bisogno di differenti varianti di un algoritmo.
  • Un algoritmo utilizza dati che i colui che li richiama non conosce.
  • Una classe definisce molti comportamenti ed esegue una serie di istruzioni condizionali multiple. Invece di molte istruzioni condizionali, ognuna viene inserita all’interno della propria classe Strategy

Partecipanti:

  • Startegy → dichiara una interfaccia comune a tutti gli algoritmi supportati. Context utilizza questa interfaccia per richiamare l’algoritmo definito da ConcreteStrategy
  • ConcreteStrategy → implementa gli algoritmi in base alla interfaccia Strategy
  • Context → è configurato con un oggetto di tipo ConcreteStrategy, mantiene un riferimento con l’oggetto Strategy, può definire una interfaccia che permette a Strategy di accedere ai propri dati

Conseguenze:

Il pattern Strategy ha queste conseguenze:

  • Vengono create famiglie di algoritmi
  • Rappresenta una alternativa all’utilizzo di sottoclassi, in fatti l’ereditarietà rappresenta un modo diverso di gestire vari algoritmi
  • Le strategie eliminato le istruzioni condizionali
  • Viene fornita una scelta dal punto di vista implementativo, infatti ci possono essere diverse implementazioni per o stesso comportamento
  • I Clients sono consapevoli delle diverse strategie adottabili
  • Esiste un sovraccarico di comunicazione tra strategia a contesto
  • Cresce sensibilmente il numero di oggetti.

Post

State

In Design Patterns on marzo 27, 2010 di poyblog Messo il tag: ,

Intento:

Permettere ad un oggetto di cambiare il proprio comportamento quando cambia il suo stato interno. L’oggetto pare che cambi la propria classe,

Applicabilità:

Il pattern State è da utilizzare nei seguenti casi:

  • Il comportamento di un oggetto dipende dal proprio stato e l’oggetto stesso deve cambiale il proprio comportamento in base allo stato durante l’esecuzione.
  • Le operazioni da fare hanno istruzioni condizionali multiple e molto corpose che dipendono dallo stato dell’oggetto. Il pattern State inserisce ogni istruzione in una classe separata.

Partecipanti:

  • Context → definisce una interfaccia per i Clients e mantiene una istanza di una sottoclasse di tipo ConcreteState la quale definisce lo stato corrente.
  • State → definisce una interfaccia per incapsulare il comportamento associato ad un particolare stato di Context
  • ConcreteState subclasses → ogni sottoclasse implementa uno specifico comportamento associato ad uno stato del contesto.

Conseguenze:

  • Con il pattern State come prima conseguenza si ha che vengono localizzati i comportamenti specifici per ogni stato e vengono suddivisi i comportamenti in riferimento agli stati. Infatti tutti i comportamenti associati ad uno specifico stato vengono inseriti tutti all’interno di un oggetto
  • Le transazioni di stato divengono esplicite
  • Lo stato degli oggetti può essere condiviso

Post

Observer

In Design Patterns on marzo 26, 2010 di poyblog Messo il tag: ,

Intento:

Definire una dipendenza di tipo uno a molti fra oggetti così che quando uno dei molti oggetti cambia stato anche tutti quelli riferiti allo stesso vengono aggiornati di conseguenza.

Applicabilità:

Il pattern Observer è da utilizzare quando:

  • una astrazione ha due aspetti diversi l’uno che dipende dall’altro. Incapsulare questi due aspetti in oggetti separati permette di variare e riutilizzare questi in modo indipendente.
  • Il cambiamento di un oggetto richiede l’aggiornamento anche di altri oggetti, dei quali non si conosce il numero
  • un oggetto deve essere in grado di aggiornare altri oggetti senza sapere chi sono questi oggetti

Partecipanti:

  • Subject → conosce i suoi osservatori. Un numero variabile di Observer può osservare un soggetto; fornisce inoltre una interfaccia per agganciare e sganciare oggetti di tipo Observer
  • Observer → definisce una interfaccia di aggiornamento per notificare tutti gli oggetti dell’avvenuto cambiamento nel soggetto
  • ConcreteSubject → mantiene gli stati di interesse degli oggetti ConcreteObserver. Invia una notifica ai suoi osservatori quando cambia stato
  • ConcreteObserver → mantiene un riferimento rispetto all’oggetto ConcerteSubject; immagazzina gli stato che potrebbero essere consistenti con quello dei soggetti ed infine implementa Observer aggiornando l’interfaccia per mantenerla al passo con quella del soggetto

Conseguenze:

  • Viene astratto l’accoppiamento fra Soggetto e Osservatore.
  • Viene supportata la comunicazione di tipo broadcast
  • Possono esserci però degli aggiornamento non aspettati che compromettono l’intera struttura, dato che un solo aggiornamento comporta il cambio anche ti tutti gli oggetti correlati

Post

Memento

In Design Patterns on marzo 25, 2010 di poyblog Messo il tag: , ,

Intento:

Senza violare l’incapsulamento, cattura lo stato interno di un oggetto e lo “esterna” così che l’oggetto può essere ripristinato al suo stato precedente.

Applicabilità:

Memento è da utilizzare nel caso in cui:

  • uno snapshot (istantanea) di un oggetto o di una parte di esso deve essere salvata al fine di poter ripristinare il suo stato in un momento successivo
  • una interfaccia diretta al fine di ottenere lo stato dell’oggetto potrebbe esporre il dettaglio implementativo dell’oggetto stesso e rompere l’incapsulamento.

Partecipanti:

  • Memento → Mantiene lo stato interno dell’oggetto Originator, inoltre protegge lo stesso oggetto da altri oggetti
  • Originator → crea l’oggetto Memento che contiene l’istantanea dello stato corrente di Originator, utilizza Memento per ripristinare un suo stato precedente
  • Caretaker → è responsabile della custodia di Memento, ma non ne gestisce o esamina il contenuto

Conseguenze:

  • Vengono preservati i limiti dell’incapsulamento, infatti Memento espone quelle informazioni che solo un oggetto Originator potrebbe gestire, ma che non potranno mai essere immagazzinate all’esterno dell’originator stesso
  • Originator stesso viene semplificato.
  • Sfruttare questo pattern può essere dispendioso in termini di risorse
  • Ci sono dei costi nascosti nella gestione dello stato degli oggetti

Post

Mediator

In Design Patterns on marzo 24, 2010 di poyblog Messo il tag: ,

Intento:

Definire un oggetto che incapsula il modo in cui gli oggetti interagiscono fra loro. Il pattern Mediator promuove il basso livello di accoppiamento fra gli oggetti mantenendo i riferimenti fra gli oggetti stessi ed in più lascia la possibilità di variare il loro modo di interagire.

Applicabilità:

E’ utile sfruttare Mediator quando:

  • un insieme di oggetti comunica in un modo ben definito ma complesso, in questo caso le interdipendenze fra oggetti sono non strutturate e difficili da comprendere.
  • Il riutilizzo di un oggetto è complesso perché contiene riferimenti e comunica con molti altri oggetti.
  • un comportamento che deve essere distribuito fra molte classi potrebbe essere personalizzato senza utilizzare una serie infinita di sottoclassi

Partecipanti:

  • Mediator → definisce una interfaccia per comunicare con l’oggetto Colleague
  • ConcreteMediator → implementa il comportamento di collaborazione al fine di coordinare gli oggetti Colleague, in più mantiene e conosce i suoi “colleghi”
  • ColleagueClasses → ogni classe di tipo Colleague conosce il proprio oggetto Mediator, ed ogni collega comunica con il proprio mediatore quando vorrebbe interagire con un altro collega.

Conseguenze:

Ecco le conseguenze dello sfruttamento del pattern Mediator:

  • Viene limitato il numero di sottoclassi; difatti il mediatore localizza i comportamenti che altrimenti sarebbero stati distribuiti attraverso più oggetti
  • Disaccoppia i colleghi, difatti viene adottato il basso livello di accoppiamento fra oggetti
  • Semplifica il protocollo di comunicazione fra oggetti, infatti i legami molti a molti fra oggetti si trasformano in legami uno a molti tra mediatore ed oggetti
  • Astrae come gli oggetti cooperano, difatti il mediatore si basa solo sulla cooperazione fra oggetti senza conoscere il loro comportamento
  • Viene centralizzato il controllo. Infatti viene tradotta la complessità dell’interazione fra oggetti nella complessità del mediatore

Post

Iterator

In Design Patterns on marzo 23, 2010 di poyblog Messo il tag: ,

Intento:

Fornire un metodo di accesso sequenziale ad un oggetto aggregato senza esporre la sua rappresentazione interna.

Applicabilità:

Il pattern Iterator è da utilizzare quando:

  • si vuole accedere al contenuto di un oggetto aggregato senza esporre la sua rappresentazione interna
  • si vuole fornire più metodi di scorrimento degli oggetti aggregati
  • si vuole fornire una interfaccia univoca per scorrere diverse strutture aggregate

Partecipanti:

  • Iterator → definisce una interfaccia per scorrere ed accedere elementi
  • ConcreteIterator → implementa l’interfaccia di Iterator e tiene traccia della posizione corrente durante la fase di attraversamento dell’oggetto aggregato
  • Aggregate → definisce l’interfaccia per creare un oggetto Iterator
  • ConcreteAggregate → implementa l’interfaccia di creazione di Iterator al fine di restituire un istanza di ConcreteIterator

Conseguenze:

Le maggiori conseguenze che scaturiscono dallo sfruttamento del pattern Iterator sono:

  • Sono supportate variazioni nel modo di scorrere l’oggetto aggregato. In particolare questa proprietà è utile quanto si cerca di attraversare complesse strutture
  • L’utilizzo di Iterator semplifica l’interfaccia di Aggregate.
  • Più di un attraversamento può rimanere attivo su di un oggetto aggregato

Post

Interpreter

In Design Patterns on marzo 22, 2010 di poyblog Messo il tag: , ,

Intento:

Dato un linguaggio, il pattern definisce una rappresentazione della propria grammatica attraverso la quale vengono interpretate le sentenze di un linguaggio

Applicabilità:

Il pattern Interpreter è da utilizzare quando vi è un linguaggio da interpretare ed è possibile rappresentare le dichiarazioni dello stesso come alberi sintattici astratti. Interpeter vine sfruttato al meglio quando:

  • la grammatica è semplice. Infatti per grammatiche complesse la gerarchia delle classi generate sarebbe troppo complessa ed ingestibile
  • L’efficienza non deve essere un aspetto critico.

Partecipanti:

  • AbstractExpression → definisce una operazione Interpreter di tipo astratto che è comune a tutti i nodi nell’albero della sintassi
  • TerminalExpression → Implementa una operazione di interpretazione con simboli terminali nella sintassi, in più viene richiesta una istanza per ogni simbolo terminale della sintassi
  • NonTerminalExpression → ogni classe vine sfruttata per ogni ruolo gestito nella grammatica, vengono mantenute le variabili di istanziazione delle AbstractExpression; infine implementa un interprete per ogni simbolo non terminale della grammatica.
  • Context → contiene informazioni che sono globali per l’interprete
  • Client → costruisce una sintassi astratta che rappresenta una particolare sentenza in un linguaggio che la grammatica stessa definisce, e invoca l’operazione di interpretazione

Conseguenze:

  • E’ facile cambiare e(o estendere una grammatica, dato che il pattern utilizza le classi per rappresentare le regole della grammatica
  • Implementare la grammatica è più facile
  • Le grammatiche complesse sono difficili da mantenere
  • E’ possibile aggiungere nuovi modi per interpretare le espressioni.

Post

Command

In Design Patterns on marzo 19, 2010 di poyblog Messo il tag: , , ,

Intento:

Incapsulare una richiesta come se fosse un oggetto, quindi lasciare la possibilità di parametrizzare i vari Client in base alle richieste effettuate. In più aggiunge la possibilità di loggare o accodare richieste e supportare operazioni altrimenti non fattibili .

Applicabilità:

E’ utile sfruttare il Pattern Command nel caso n cui si voglia:

  • parametrizzare gli oggetti per eseguire una determinata operazione
  • specificare, accodare ed eseguire richieste in differenti periodi di tempo; difatti un oggetto di tipo Command può avere un tempo di vita indipendente rispetto alla richiesta originale
  • sia supportata l’operazione di undo (operazione che rende possibile tornare allo stato precedete dell’operazione in questione)
  • ci sia il supporto per effettuare cambiamenti nel processo di logging in modo tale che sia possibile riabilitare il sistema in caso di crash.
  • Strutturare un sistema attorno a operazioni ad alto livello costruite però su operazioni primitive, in parole povere un sistema che supporti le transazioni.

Partecipanti:

  • Command → dichiara una interfaccia per eseguire una operazione
  • ConcreteCommand → definisce un legame fra l’oggetto Receiver e l’azione; implementa l’operazione Execute invocando la corrispondente operazione/i presenti nel Receiver
  • Client → crea un oggetto ConcreteCommand e imposta il Receiver
  • Invoker → richiede il comando per convogliare la richiesta
  • Receiver → conosce come gestire le operazioni associate al trasporto della richiesta. Ogni classe può essere n Receiver

Conseguenze:

  • In primis il pattern disaccoppia gli oggetti che invocano l’operazione da quelli che conoscono come eseguirla
  • I Commands sono veri e propri oggetti e come tali possono essere estesi e manipolati
  • Si possono assemblare più commad creando un composite command
  • E’ facile aggiungere nuovi Command dato che non è necessario variare alcuna classe esistente.

Post

Chain of Responsibility

In Design Patterns on marzo 18, 2010 di poyblog Messo il tag: ,

Intento:

Permette di agganciare il mittente di una richiesta con il ricevitore, lasciando la possibilità a più di un oggetto di gestire la richiesta. Una volta concatenati gli oggetti “ricettori” la richiesta viene passata attraverso la catena stessa fino a che un oggetto non la prende in carico.

Applicabilità:

Il pattern è da utilizzare quando:

  • più di un oggetto è in grado di gestire una richiesta e non c’e nessun oggetto che possa gestire la richiesta a priori
  • si vuole gestire una richiesta con uno dei molti oggetti presenti, senza indicare il ricevitore esplicitamente
  • l’insieme di oggetti che possono gestire la richiesta dovrebbero essere specificati dinamicamente.

Partecipanti:

  • Handler → definisce una interfaccia per gestire le richieste e può implementare la successione degli elementi nella catena
  • ConcreteHandler → gestisce le richieste e ne è responsabile, è poi in grado di accedere al successore (altro elemento della catena). Se il ConcreteHandler può gestire la richiesta, questo può elaborarla oppure inviarla al successore
  • Client → Inizializza la richiesta verso un oggetto di tipo ConcreteHamdler

Conseguenze:

Ecco i benefici e i vincoli che tale pattern comporta:

  • Viene ridotto il livello di accoppiamento, dato che viene liberato ogni oggetto dalla necessità di conoscere tutti coloro che sono in grado di risolvere tale richiesta.
  • Viene aggiunta flessibilità nella fase di assegnazione di responsabilità agli oggetti
  • La ricezione e la gestione delle richieste non sono garantite
Iscriviti

Get every new post delivered to your Inbox.