190 likes | 418 Views
Template Method Design Pattern. But. Définir le squelette d’un algorithme tout en déléguant certaines étapes aux sous-classes. Les sous-classes peuvent redéfinir certaines étapes de l’algorithme sans en changer la structure. Exemple . public class Application
E N D
But • Définir le squelette d’un algorithme tout en déléguant certaines étapes aux sous-classes. • Les sous-classes peuvent redéfinir certaines étapes de l’algorithme sans en changer la structure.
Exemple public class Application {… public OpenDocument (String name) { if (!CanOpenDocument(name)) { // cannot handle this document return; } Document doc =DoCreateDocument(); if (doc != null) { _docs.AddDocument(doc); AboutToOpenDocument(doc); doc.Open(); doc.DoRead(); } } }
Exemple • La méthode template définit l’algorithme en termes d’opérations abstraites. • Les sous-classes les redéfinissent pour spécifier le comportement concret de différentes étapes de l’algorithme • Est-ce que le document peut être ouvert? (CanOpenDocument) • Création du document (DoCreateDocument) • Lecture du document (DoRead). • Informer les sous-classes que le document va être ouvert au cas où elles s’en préoccuperaient (AboutToOpenDocument). • La méthode “template” fixe l’ordre des opérations, mais laisse la possibilité aux sous-classes de définir les détails de ces opérations.
Quand appliquer le patron Template Method? • Pour implémenter les parties invariantes d’un algorithme une seule fois et laisser aux sous-classes le soin d’implémenter les parties qui varient. • Lorsqu’un comportement commun entre des sous-classes devrait être factorisé et placé dans une classe commune afin d’éviter la duplication de code • "refactoring to generalize" • Identifer les différences dans le code existant • Extraire ces différences dans de nouvelles méthodes • Utiliser le template method pour appeler ces méthodes • Pour contrôler les extensions des sous-classes • Définir une méthode template qui appelle des méthodes "hook" en des points spécifiques de manière à ne permettre les extensions seulement qu’en ces points
Participants • AbstractClass (Application) • Définit les méthodes abstraites de base que les sous-classes doivent implémenter pour les diverses étapes de l’algorithme. • Implémente la méthode “template” qui définit le squelette de l’algorithme. • Cette méthode invoque aussi bien les méthodes abstraites que les méthodes définies dans AbstractClass ou celles de d’autres objets. • ConcreteClass (MyApplication) • Implémente les opérations abstraites pour réaliser les étapes spécifiques aux sous-classes
Collaborations entre les classes • ConcreteClass repose sur AbstractClass pour l’implémentation des étapes invariantes de l’algorithme
Exemple : refactorisationClasse abstraite public abstract class TextDocument { … public final void printPage(Page page) { printTextHeader(); printTextBody(page); printTextFooter(); } protected abstract void printTextHeader(); protected abstract void printTextBody(Page page); protected abstract void printTextFooter(); … }
Conséquences I • Une technique fondamentale pour la réutilisation du code • Particulièrement importante dans les librairies de classes • Le moyen pour factoriser les comportements communs • Une structure de contrôle inversée • "the Hollywood principle," that is, "Don't call us, we'll call you" • La classe parent appelle les méthodes des sous-classes et non l’inverse. • Un template method invoque en général les types de méthodes suivants: • Méthodes concrètes de ConcreteClass ou de classes clients; • Méthodes concrètes de AbstractClass • Méthodes abstraites • factory methods • Méthodes “hook”, • Comportement par défaut que les sous-classes peuvent redéfinir • Souvent ces méthodes sont vides. • Afin de bien réutiliser une classe abstraite, il faut bien identifier • Les méthodes “hook” qui peuvent être redéfinies • Les méthodes abstraites qui doivent être redéfinies.
Conséquences II • Une sous-classe peut spécialiser une méthode d’une classe parent • en redéfinissant cette méthode • et en invoquant la méthode de la superclasse explicitement Public class DerivedClass extends ParentClass { public void operation () {super.operation(); } } • Cependant, il facile d’oublier l’invocation de la méthode de la superclasse • Transformation en méthode “template” pour donner le contrôle à la classe parent • La classe parent définit une méthode hook que les sous-classe peuvent redéfinir Public class ParentClass { “final” public void operation () {HookOperation(); } pubic void hookOperation () { }}} • Les sous-classes redéfinissent HookOperation : Public class DerivedClass extends ParentClass { public void hookOperation () { // DerivedClass extended behavior } }
Implémentation • Méthodes abstract, protected, final • Minimiser les méthodes abstraites. • Plus il y aura de méthodes à définir, plus ce sera fastidieux • Définir des conventions au niveau des noms. • Par exemple, pour définir les méthodes qui devraient être redéfinies, utiliser un préfixe. • Dans le MacApp framework pour les applications Macintosh Le nom des méthodes relatives à un template method commencent avec "Do-“ • "DoCreateDocument", "DoRead", etc.
Design Patterns reliés • Factory Methods • souvent appelés par les template methods • la méthode DoCreateDocument de la méthode OpenDocument de l’exemple. • Strategy • Les méthodes Template utilisent l’héritage pour faire varier des parties d’un algorithme • Les stratégies utilisent la délégation pour faire varier tout l’algorithme.
Références • William F. Opdyke and Ralph E. Johnson. Creating abstract superclasses by refactoring. In Proceedings of the 21st Annual Computer Science Conference (ACM CSC '93), pages 66–73, Indianapolis, IN, February 1993 • Rebecca Wirfs-Brock and Ralph E. Johnson. A survey of current research in object-oriented design. Communications of the ACM, 33(9):104–124, 1990
Strategy DP • Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
Strategy - exemple • Composition class • responsible for maintaining and updating the linebreaks of text displayed in a text viewer. • Compositor subclasses implement different strategies: • SimpleCompositor implements a simple strategy that determines linebreaks one at a time. • TeXCompositor implements the TeX algorithm for finding linebreaks. This strategy tries to optimize linebreaks globally, that is, one paragraph at a time. • ArrayCompositor implements a strategy that selects breaks so that each row has a fixed number of items. It's useful for breaking a collection of icons into rows, for example. • A Composition maintains a reference to a Compositor object. Whenever a Composition reformats its text, it forwards this responsibility to its Compositor object.