30
Command Design Pattern

Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Embed Size (px)

Citation preview

Page 1: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Command Design Pattern

Page 2: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Intention Encapsuler une requête sous forme d’objet

paramétrer les clients avec différentes requêtes,

files de requêtes

“logs” de requêtes

support d’opérations réversibles (“undo”)

Page 3: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Motivation Le framework Swing émet des requêtes aux objets

lorsque les items des menus sont activés les boutons sont “cliqués”.

Swing ne peut pas implémenter ces requêtes car elles sont spécifiques aux applications.

Comment émettre des requêtes à des objets sans rien connaître des opérations demandées ? ou sans rien connaître de celui à qui la requête est

destinée ?

Page 4: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Motivation Le design pattern Command permet

aux objets d’un toolkit de faire des requêtes sur des objets d’une application non-spécifiée en transformant la requête en un objet

Cet objet est emmagasiné et transmis commes les autres objets.

dissocie l’objet qui invoque une opération de l’objet qui possède les connaissances nécessaires pour réaliser cette opération.

Flexibilité au niveau du design de l’interface-usager. Partage de fonctionnalités

Une application peut fournir un menu et un bouton pour une fonctionnalité juste en faisant en sorte que le menu et le bouton partagent une instance de la même sous-classe de Command.

Remplacement dynamique des commandes Utile pour l’implémentation de menus dépendants du contexte (context-sensitive menus).

Définition de scripts par composition de commandes

possible parce que l’objet qui émet la requête n’a besoin de ne savoir que comment l’émettre, et non pas de savoir comment la requête va être exécutée.

Toolkit: The property of the Java API that defines the look and feel of the user interface on a specific platform

Page 5: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Application : Toolkit

Page 6: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Commande simple

Page 7: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Commande complexe

Page 8: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Liste de commandes

Page 9: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Quand appliquer le patron Command? Pour paramétriser des objets par une action à exécuter

Exemple: objets MenuItem Les commandes servent à remplacer les “callback” dans les langages orientés objets.

Dans un langage procédural >>> une fonction callback function, une fonction enregistrée en quelque part qui doit être appelée plus tard

Pour spécifier, mettre en file, et exécuter les requêtes à des moments différents Le cycle de vie d’un objet Command est indépendant de la requête originale

Pour implémenter des opération réversibles. L’exécution de la commande peut conserver l’état dans la commande elle-même pour

inverser son effet. Ajout d’une méthode “unexecute” Les commandes exécutées sont placées dans une liste.

Pour implémenter un log des modifications de telle sorte que l’on puisse les réappliquer en cas d’écroulement du système.

Ajout des méthodes “load” et “store”

Pour structurer un système à l’aide d’opérations de haut niveau construites à partir d’opérations primitives

Transactions Une transaction encapsule une ensemble de modification aux données.

Page 10: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Structure

Page 11: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Participants Command

déclare une interface pour exécuter une opération.

ConcreteCommand (PasteCommand, OpenCommand) Définit une liaison entre l’objet destinataire et l’action Implémente “execute” par l’invocation d’ opérations sur le

destinataire.

Client (Application) Crée un objet ConcreteCommand et assigne son destinataire.

Invoker (MenuItem) Demande à la commande de s’exécuter.

Destinataire (Document, Application) Sait comment exécuter les opérations associées à la requête. N’importe quelle classe peut agir comme destinataire.

Page 12: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Collaborations Le client crée l’objet

ConcreteCommand et spécifie le destinataire.

L’objet Invoker emmagasine l’objet ConcreteCommand.

L’objet “invoker” émet une requête en invoquant “execute” sur la commande.

Lorsque la commande est réversible, ConcreteCommand emmagasines l’état nécessaire pour retourner dans l’état précédent l’invocation de “Execute”.

L’objet ConcreteCommand invoque les opérations du destinataire pour exécuter la requête.

Page 13: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Conséquences Le Command DP dissocie l’objet qui invoque une

opération de celui qui sait comment l’exécuter.

Les commandes sont des objets à part entière. Elles peuvent être manipulées et étendues comme n’importe quel autre objet.

On peut assembler des commandes pour former une commande composite.

Composite pattern.

C’est facile d’ajouter de nouvelles commandes car il ne faut pas modifer les classes existantes.

Page 14: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Implémentation Jusqu’à quel point une commande devrait-elle être

intelligente?

À une extrême, seulement un lien entre un destinataire et les actions à effectuer.

Commandes qui possèdent assez de connaissances pour trouver leur destinataire dynamiquement.

A l’autre extrême, la commande fait tout sans rien déléguer à un destinataire

Pour définir des commandes indépendantes des classes existantes.

Lorsqu’aucun destinataire acceptable n’existe. Une commande connaît son destinataire implicitement

(création d’une fenêtre)

Page 15: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Implémentation Implémentation de “undo” et “redo”

Quel état faut-il conserver? Destinataire Arguments Valeurs originales de l’état du destinataire qui ont pu être

modifiées par la commande

Combien de niveau de “undo” Seulement la dernière commande History list

Une commande réversible peut devoir être clonée avant de la placer dans l’historique pour distinguer diverse invocations de la même commande.

Prototype DP

Page 16: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Implémentation Eviter l’accumulation d’erreurs dans le processus

de réversibilité

Assurer un mécanisme undo/redo fiable préservant la sémantique

Les erreurs peuvent s’accumuler lorsque les commandes sont exécutés, inversées et réexécutées.

Le Memento (283) DP peut être appliqué pour donner accès à l’information nécessaire pour restaurer un objet sans exposer les détails internes d’un objet.

Page 17: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Exemple : Swing

http://www.javaworld.com/javaworld/jw-06-2002/jw-0628-designpatterns.html

Page 18: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”
Page 19: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

execute

Page 20: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Known Uses Perhaps the first example of the Command pattern appears in a paper by Lieberman [Lie85].

H. Lieberman. There's more to menu systems than meets the screen. SIGGRAPH Computer Graphics, pp. 181–189, San Francisco, July 1985 MacApp [App89] popularized the notion of commands for implementing undoable operations.

ET++ [WGM88], InterViews [LCI+92], and Unidraw [VL90] also define classes that follow the Command pattern.

InterViews defines an Action abstract class that provides command functionality. It also defines an ActionCallback template, parameterized by action method, that can instantiate command subclasses automatically.

The THINK class library [Sym93b] also uses commands to support undoable actions. Commands in THINK are called "Tasks." Task objects are passed along a Chain of Responsibility (223) for

consumption.

Unidraw's command objects are unique in that they can behave like messages. A Unidraw command may be sent to another object for interpretation, and the result of the interpretation varies with

the receiving object. Moreover, the receiver may delegate the interpretation to another object, typically the receiver's parent in a larger structure as in a Chain of Responsibility. The receiver of a Unidraw command is thus computed rather than stored. Unidraw's interpretation mechanism depends on run-time type information.

Coplien describes how to implement functors, objects that are functions, in C++ [Cop92]. He achieves a degree of transparency in their use by overloading the function call operator (operator()). The Command pattern is different; its focus is on maintaining a binding between a receiver and a function (i.e., action), not just maintaining a function.

Page 21: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Patterns reliés Composite >>> Macro-commandes

Memento >>> conserver l’état d’un destinataire lorsqu’une commande est réversible.

Une commande qui doit êtr copiée avant d’être placée dans un historique agit commun un Prototype.

Page 22: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Références Gamma et al., Design Patterns,

http://www.javaworld.com/columns/jw-java-design-patterns-index.shtml

Page 23: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

Struts

Struts, a popular open source JSP application framework from the Apache Software Foundation

But the most significant cog in the Struts wheel is an MVC framework that revolves around the Command pattern.

Page 24: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

All Web applications, at their core, perform the same basic function:

field HTTP requests and respond to those requests by performing some application-specific functionality.

Struts provides a servlet—known as the action servlet—that handles HTTP requests and ultimately invokes an application-specific action.

The Struts action servlet turns HTTP requests into actions, but as a developer employing Struts to implement Web applications, you can remain blissfully ignorant of how it works—that's the beauty of application frameworks and the Command pattern.

You simply need to know how to map an HTTP request to a Struts action, how to implement that action, and you're off and running.

Page 25: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”
Page 26: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”
Page 27: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”
Page 28: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

The preceding configuration file maps the /simple URL to the actions.SimpleAction class.

When the action servlet receives the /simple.do URL, it strips off the .do suffix and maps the URL to the actions.SimpleAction class. If an instance of that class does not exist,

the action servlet creates one and invokes its execute() method.

Page 29: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”
Page 30: Command Design Pattern. Intention Encapsuler une requête sous forme d’objet paramétrer les clients avec différentes requêtes, files de requêtes “logs”

The preceding action checks to see if a counter bean exists in the application scope; if not, it creates one and stores it there. Subsequently, the action invokes the counter bean's updateCount() method, which updates a counter stored in a file named .simpleActionCount. Then the action returns an ActionForward instance that points to a JSP mapped to the string fwd-page. That mapping, also defined in the Struts configuration file (see Example 4), resolves the string fwd-page to the forwardPage.jsp JSP. The action servlet subsequently forwards control to that JSP