Command pattern: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
Nessun oggetto della modifica |
m →Altri progetti: Aggiunto il parametro "Preposizione" nel template "Interprogetto" |
||
(56 versioni intermedie di 41 utenti non mostrate) | |||
Riga 1:
Nella [[Programmazione orientata agli oggetti|programmazione a oggetti]], il '''Command pattern''' è uno dei pattern fondamentali, definiti originariamente dalla [[Gang of Four (scrittori)|Gang of Four]].
Questo Pattern permette di isolare la porzione di codice che effettua un'azione (eventualmente molto complessa) dal codice che ne richiede l'esecuzione; l'azione è incapsulata nell'oggetto Command.▼
▲
L'obiettivo è rendere variabile l'azione del client senza però conoscere i dettagli dell'operazione stessa. Altro aspetto importate è che il destinatario della richiesta può non essere deciso staticamente all'atto dell'istanziazione del command ma ricavato a run-time.▼
▲L'obiettivo è rendere variabile l'azione del client senza però conoscere i dettagli dell'operazione stessa. Altro aspetto
==Struttura==▼
▲== Struttura ==
[[Immagine:CommandPattern.png|center|Struttura del Design Pattern '''Command''']]▼
▲[[
==Esempio==▼
▲== Esempio ==
In un modulo (python) è definita la classe che segue.
<syntaxhighlight lang=python>
class RoomHandler:
...
</syntaxhighlight>
Sono infatti
<syntaxhighlight lang=python>
class Painter(RoomHandler)
...
Riga 38 ⟶ 39:
def actionWork(self, arguments):
""" mount shelves to some walls """
</syntaxhighlight>
1. Se esistono ''n'' possibili lavori (azioni) ci si ritrova costretti ad avere molte sottoclassi. Non solo una per azione da implementare ma anche quelle che servono per le possibili combinazione di azioni che voglio ottenere (ad esempio dipingere camera e montarci degli scaffali). Se invece le azioni sono ''Command'' indipendenti dal RoomHandler, posso istanziarli su quest'ultimo senza dover subclassare.▼
Questo approccio presenta diversi aspetti negativi.
2. Se ''RoomHandler'' contiene sia il codice di gestione delle camere che il codice che svolge i lavori: in sostanza ha troppe responsabilità e se voglio estendere un lavoro devo complicare di conseguanza anche ''RoomHandler''.▼
▲
3. Testare oggetti così complessi, con molte responsabilità, diventa faticoso e complesso. Se le azioni sono incapsulate in ''Command'' testate separatamente riesco a semplificare anche i test (eventualmente ricorrendo all'uso di [[Mock Objects|Mock]].▼
▲
▲
Segue il codice equivalente strutturato seguendo le indicazioni del pattern:
<syntaxhighlight lang=python>
class Command:
Riga 70 ⟶ 69:
def execute(self, wall):
""" mount shelf to a wall """
</syntaxhighlight>
<syntaxhighlight lang=python>
def createRoomHandler(self):
handler = RoomHandler()
Riga 85 ⟶ 84:
for work in self.getWorks():
work.execute(self.getSelectedWall())
</syntaxhighlight>
== Considerazioni ==▼
▲==Considerazioni==
== Bibliografia ==
▲1. Il ricevente dell'operazione (nel nostro caso la parete dove lavorare) non è deciso al momento della creazione dei lavori da svolgere, ma a tempo di esecuzione.
* [[Erich Gamma|Gamma, E.]], [[Richard Helm|Helm, R.]], [[Ralph Johnson (informatico)|Johnson, R.]] e [[John Vlissides|Vlissides, J.]], '' [[Design Patterns]]: elementi per il riuso di software a oggetti'', Addison Wesley, 1995, ISBN 88-7192-150-X.
** Originale: ''Design Patterns: Elements of Reusable Object-Oriented Software'', Addison Wesley, 1995, ISBN 0-201-63361-2.
== Altri progetti ==
▲2. E' possibile incapsulare un'azione in modo che essa sia atomica. In questo modo si implementerebbe un meccanismo di transazionalità in cui un'insieme di operazioni è svolto in toto o per nulla.
{{interprogetto|preposizione=sul}}
{{Design pattern}}
▲3. I ''Command'', conoscendo le operazioni che devono svolgere, possono implementare anche un ''unexecute'' o ''undo''. Prima di eseguire, il Command, ricorda lo stato precedente alla sua esecuzione in modo da annullare eventualmente la sua operazione.
{{Portale|informatica}}
[[Categoria:Design pattern]]
▲4. E' possibile rendere asincrona la scelta dei comandi rispetto alla loro esecuzione. Un certo numero di command, selezionati da un client, possono essere ''consumati'' da un'altro oggetto che li riceve in un tempo diverso dalla loro selezione.
|