Nella [[Programmazione_orientata_agli_oggettiProgrammazione orientata agli oggetti|programmazione ada oggetti]], il '''Command pattern''' è uno dei pattern fondamentali, definiti originariamente dalla [[gangGang of Four (scrittori)|Gang of fourFour]].
Il Command pattern è uno dei [[design pattern]] che 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 importante è che il destinatario della richiesta può non essere deciso staticamente all'atto dell'istanziazione del command ma ricavato a tempo di esecuzione.
== Struttura ==
[[ImmagineFile:CommandPattern.png|center|Struttura del Design Pattern '''Command'''|bordo|549x549px]]
== Esempio ==
In un modulo (python) è definitodefinita illa seguenteclasse oggetto.che segue.
<syntaxhighlight lang=python>
<pre>
class RoomHandler:
...
</syntaxhighlight>
</pre>
EssoQuesta è destinatodestinata ada occuparsi della gestione delle camere di una casa enonché, attualmente, presiede anche allo svolgimento di alcuni lavori da eseguire.
Sono infatti definite, per ereditarietà, alcune sottoclassi che implementano diversi lavori diversiche è dapossibile svolgere sulle pareti delle camere.
<syntaxhighlight lang=python>
<pre>
class Painter(RoomHandler)
...
def actionWork(self, arguments):
""" mount shelves to some walls """
</syntaxhighlight>
</pre>
Questo approccio hapresenta alcunediversi conseguenzeaspetti negativenegativi.
# SeA esistonofronte di ''n'' possibili lavori (azioni) ci si ritrovarendono costrettinecessarie ad avere moltediverse sottoclassi. Non solo: una per ciascuna azione da implementare mae anche quelle che servonouna per leogni possibilipossibile combinazionecomposizione di azioni che voglio ottenerebase (adper esempio dipingere camera e montarcimontare deglidi seguito gli scaffali). SeQualora invece le azioni sonofossero ''Command'' indipendenti dal RoomHandler, possosarebbe istanziarlipossibile creare istanze su quest'ultimo senzapiuttosto doverche subclassarecreare sottoclassi.
# ''RoomHandler'' contiene sia il codice di gestione delle camere che il codice che svolgeesegue ile lavoriazioni: inesso sostanzaè hasovraccarico troppedi responsabilità e se voglioed estendere un'azione lavorocomporta devoun complicareaumento didella conseguanzacomplessità anchedel ''RoomHandler''.
# Testare oggetti così complessi, con moltenumerose responsabilità, diventaè faticosoin egenere complesso e oneroso. SeIncapsulare le azioni sono incapsulate in ''Command'' testaterende separatamentepossibile riescoil atesting semplificareesclusivo anchesu iciascuna testazione (eventualmente ricorrendo all'uso di [[Mock Objects|Mock]]) il che semplifica notevolmente la fase di testing e validazione.
Segue il codice equivalente strutturato seguendo le indicazioni del pattern:
Volendo quindi rifattorizzare il codice precedente:
<syntaxhighlight lang=python>
<pre>
class Command:
def execute(self, wall):
""" mount shelf to a wall """
</syntaxhighlight>
</pre>
AlSia momentonell'atto delladi creazione di un'istanza ''RoomHandler'', sia a ''run-time'', è possibile selezionare ile azioni possibiliche lavorisi daintende svolgere:
<syntaxhighlight lang=python>
<pre>
def createRoomHandler(self):
handler = RoomHandler()
for work in self.getWorks():
work.execute(self.getSelectedWall())
</syntaxhighlight>
</pre>
== Considerazioni ==
# Il riceventeL'oggetto dell'operazione (nel nostro casonell'esempio unala parete) non è deciso al momento della creazione deidelle lavoriazioni ma a tempo di esecuzione.
# È possibile incapsulare un'azione in modo che essaquesta sia atomica. InÈ questocosì modopossibile si implementaimplementare un meccanismoparadigma dibasato transazionalitàsu transazioni in cui un' insieme di operazioni è svolto in toto o per nulla.
# I ''Command'', conoscendoi lequali sono a conoscenza delle operazioni che devonosono chiamati a svolgere, possono implementare anchefunzioni undi ''unexecute'' o ''undo''. SeIn necessariocasi ilcome Commandquesti, primail diCommand eseguire,può ricordamemorizzare lo stato precedente alla sua esecuzione, inripristinandolo modoqualora dal'operazione poterdebba annullareessere la sua operazioneannullata.
# È 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.
== Bibliografia ==
* [[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 887192150X88-7192-150-X.
** Originale: ''Design Patterns: Elements of Reusable Object-Oriented Software'', Addison Wesley, [[1995]], ISBN 02016336120-201-63361-2.
== Altri progetti ==
{{interprogetto|preposizione=sul}}
{{Design pattern}}
[[de:Kommando (Entwurfsmuster)]]
{{Portale|informatica}}
[[en:Command pattern]]
[[es:Command (patrón de diseño)]]
▲[[Categoria: PatternDesign pattern]]
[[fr:Commande (patron de conception)]]
[[pl:Wzorzec polecenia]]
[[ru:Command]]
[[uk:Команда (шаблон проектування)]]
[[zh:命令模式]]
|