Quelle est la différence entre la méthode du modèle et les modèles de stratégie?


161

Quelqu'un peut-il m'expliquer quelle est la différence entre le modèle de méthode modèle et le modèle de stratégie?

Pour autant que je sache, ils sont identiques à 99% - la seule différence étant que le modèle de méthode de modèle a une classe abstraite comme classe de base, tandis que la classe de stratégie utilise une interface implémentée par chaque classe de stratégie concrète.

Cependant, en ce qui concerne le client, ils sont consommés exactement de la même manière - est-ce correct?


2
Ce message dans SO a une meilleure réponse pour la même question: stackoverflow.com/questions/464524
...

12
La question à laquelle gob00st est lié est la différence entre stratégie et bridge. Ce n'est pas du tout la réponse à cette question.
bluekeys

Réponses:


135

La principale différence entre les deux réside dans le choix de l'algorithme concret.

Avec le modèle de méthode Template, cela se produit au moment de la compilation en sous - classant le modèle. Chaque sous-classe fournit un algorithme concret différent en implémentant les méthodes abstraites du modèle. Lorsqu'un client appelle des méthodes de l'interface externe du modèle, le modèle appelle ses méthodes abstraites (son interface interne) comme requis pour appeler l'algorithme.

class ConcreteAlgorithm : AbstractTemplate
{
    void DoAlgorithm(int datum) {...}
}

class AbstractTemplate
{
    void run(int datum) { DoAlgorithm(datum); }

    virtual void DoAlgorithm() = 0; // abstract
}

En revanche, le modèle Stratégie permet de choisir un algorithme lors de l' exécution par confinement . Les algorithmes concrets sont implémentés par des classes ou des fonctions séparées qui sont passées à la stratégie en tant que paramètre à son constructeur ou à une méthode setter. L'algorithme choisi pour ce paramètre peut varier dynamiquement en fonction de l'état ou des entrées du programme.

class ConcreteAlgorithm : IAlgorithm
{
    void DoAlgorithm(int datum) {...}
}

class Strategy
{
    Strategy(IAlgorithm algo) {...}

    void run(int datum) { this->algo.DoAlgorithm(datum); }
}

En résumé:

  • Modèle de méthode de modèle: sélection d'algorithme au moment de la compilation par sous-classification
  • Modèle de stratégie: sélection d' algorithme d'exécution par confinement

47
Les deux modèles prennent en charge la sélection d'exécution de l'algorithme utilisé (pour la méthode de modèle, vous feriez quelque chose du genre if (config.useAlgoA) impl = new AlgoA() else impl = new AlgoB()), donc cette réponse est incorrecte.
Borek Bernard

13
Bien sûr, vous pouvez le faire, mais vous n'utilisez pas le modèle de modèle. En fait, c'est presque exactement à quoi ressemblera le code créant l'instance de stratégie!
thehouse

21
-1, je pense que cette réponse (bien que pas complètement fausse), passe à côté du point où se trouvent les vraies différences. La réponse de @ tvanfosson est bien meilleure.
Doc Brown

1
@Karoly Nyisztor Ils peuvent tous les deux "remplacer le comportement" et "fournir des points d'extension". Qu'il s'agisse d'un comportement ou d'une extension, cela dépend vraiment du contexte dans lequel vous appliquez un modèle donné. Vous pouvez également appeler chaque sous-classe du modèle de méthode de modèle une "stratégie", ou appeler chaque classe de stratégie du modèle de stratégie une "extension", ce n'est qu'un libellé. Le fait est qu'ils font la même chose SAUF la différence mentionnée dans cette réponse. C'est donc la bonne réponse.
Andy

1
Un algorithme concret est choisi de la même manière pour les deux motifs. Le choix est fait en invoquant new ConcreteAlgorithm1()versus new ConcreteAlgorithm2(). Évidemment, le choix se produit au moment de l'exécution (faire un choix d'algorithme au moment de la compilation signifierait le coder en dur). La principale différence entre les deux réside dans la manière dont l'algorithme concret est mis en œuvre. Est-il implémenté en tant que sous-classe ou en tant qu'interface distincte? Le premier est un modèle. Ce dernier est une stratégie. La différence peut être résumée en tant que composition vs héritage, qui est un thème commun du livre du GoF.
jaco0646

138

Le modèle de modèle est utilisé lorsqu'une opération particulière a un ou plusieurs comportements invariants qui peuvent être définis en termes d'autres comportements primitifs variables. La classe abstraite définit le (s) comportement (s) invariant (s), tandis que les classes d'implémentation définissent les méthodes dépendantes.

Dans une stratégie, les implémentations de comportement sont indépendantes - chaque classe d'implémentation définit le comportement et aucun code n'est partagé entre elles. Les deux sont des modèles de comportement et, en tant que tels, sont consommés de la même manière par les clients. En règle générale, les stratégies ont une seule méthode publique - la execute()méthode, tandis que les modèles peuvent définir un ensemble de méthodes publiques ainsi qu'un ensemble de primitives privées de support que les sous-classes doivent implémenter.

Les deux modèles pourraient facilement être utilisés ensemble. Vous pouvez avoir un modèle de stratégie dans lequel plusieurs implémentations appartiennent à une famille de stratégies implémentées à l'aide d'un modèle de modèle.


Cela me semble normal , mais pourquoi WikiPedia mentionne-t-il que "le modèle de stratégie est pour le comportement d'un algorithme à être sélectionné au moment de l'exécution"? Il pourrait également être utilisé pour sélectionner le comportement de l'algorithme au moment de la compilation, tout comme la méthode du modèle? Est-ce que je manque quelque chose?
BornToCode

2
@BornToCode Je suppose que ce dont ils parlent est de choisir une stratégie particulière au moment de l'exécution. Par exemple, il existe plusieurs façons de trouver numériquement les racines d'une équation. En fonction du domaine du problème ou des données, vous pouvez choisir Newton-Raphson, Euler ou une autre stratégie pour résoudre l'équation. Chacun de ces éléments est une stratégie. L'algorithme plus large, dont la résolution de l'équation fait partie, choisit la stratégie à employer en fonction d'une certaine qualité du problème.
tvanfosson le

Oui, mais ce n'est pas comme si le modèle de stratégie devrait être utilisé UNIQUEMENT pour ces cas? Je veux dire que si je n'ai besoin que de sélectionner le comportement de l'algorithme au moment de la compilation, dois-je toujours utiliser le modèle de stratégie, ou il n'était pas destiné à être utilisé de cette façon?
BornToCode

1
@BornToCode Je dirais qu'une stratégie est plus utile lorsque le choix est dynamique. Le modèle est fondamentalement un moyen de créer des comportements différents et liés pour le connu. Vous utiliseriez une stratégie (mais pas nécessairement le modèle de stratégie) pour choisir le comportement modèle à utiliser. Par exemple, l'héritage de produit - vous créez un produit de base, ajoutez des fonctionnalités pour différents produits. Le choix du type de produit (classe) à instancier peut dépendre des tables / vues à partir desquelles il est chargé. Le modèle de stratégie n'entre pas vraiment en jeu là-bas.
tvanfosson du

2
@BornToCode ce n'est pas une chose ou / ou une chose, c'est oui-et. Appliquez le motif là où c'est approprié, combinez les motifs là où c'est utile.
tvanfosson

26

Je pense que les diagrammes de classes des deux modèles montrent les différences.

Stratégie
Encapsule un algorithme dans une classe
Lien vers l'image entrez la description de l'image ici

Méthode de modèle
Reportez les étapes exactes d'un algorithme à une sous-classe
Lien vers l'image entrez la description de l'image ici


24

Vous voulez probablement dire modèle de méthode de modèle. Vous avez raison, ils répondent à des besoins très similaires. Je dirais qu'il est préférable d'utiliser la méthode de modèle dans les cas où vous avez un algorithme de «modèle» ayant défini des étapes où les sous-classes remplacent ces étapes pour modifier certains détails. En cas de stratégie, vous devez créer une interface et au lieu de l'héritage, vous utilisez la délégation. Je dirais que c'est un modèle un peu plus puissant et peut-être meilleur conformément aux principes d'inversion de dépendance DIP. Il est plus puissant parce que vous définissez clairement une nouvelle abstraction de stratégie - une façon de faire quelque chose, qui ne s'applique pas à la méthode modèle. Donc, si cette abstraction a du sens, utilisez-la. Cependant, l'utilisation de la méthode de modèle peut vous donner des conceptions plus simples dans des cas simples, ce qui est également important. Considérez quels mots conviennent le mieux: avez-vous un algorithme de modèle? Ou est-ce que l'élément clé ici est que vous ayez une abstraction de la stratégie - une nouvelle façon de faire quelque chose

Exemple de méthode de modèle:

Application.main()
{
Init();
Run();
Done();
}

Ici, vous héritez de l'application et remplacez ce qui sera exactement fait lors de l'initialisation, de l'exécution et de la fin.

Exemple de stratégie:

array.sort (IComparer<T> comparer)

Ici, lors de l'écriture d'un comparateur, vous n'héritez pas d'un tableau. Array délègue l'algorithme de comparaison à un comparateur.


3
Je pense que c'est une excellente réponse
Calanus

23

Différence entre la stratégie et la méthode de modèle Modèle de stratégie et la méthode de modèle


Similitudes

Les modèles de méthode de stratégie et de modèle présentent de nombreuses similitudes entre eux. Les modèles de méthodes de stratégie et de modèle peuvent être utilisés pour satisfaire le principe ouvert-fermé et rendre le module logiciel facile à étendre sans changer son code. Les deux modèles représentent la séparation de la fonctionnalité générique de l'implémentation détaillée de cette fonctionnalité. Cependant, ils diffèrent un peu en termes de granularité qu'ils offrent.


Différences

Voici quelques-unes des différences que j'ai observées en étudiant ces deux modèles:

  1. En stratégie, le couplage entre le client et la stratégie est plus lâche alors que dans la méthode modèle, les deux modules sont plus étroitement couplés.
  2. Dans Strategy, une interface est principalement utilisée bien que la classe abstraite puisse également être utilisée en fonction de la situation, et la classe concrète n'est pas utilisée alors que dans la méthode Template, la classe abstraite ou la classe concrète est principalement utilisée, l'interface n'est pas utilisée.
  3. Dans le modèle de stratégie, le comportement généralement entier de la classe est représenté en termes d'interface, par contre, la méthode Template est utilisée pour réduire la duplication de code et le code standard est défini dans le cadre de base ou la classe abstraite. Dans Template Method, il peut même y avoir une classe concrète avec une implémentation par défaut.
  4. En termes simples, vous pouvez modifier toute la stratégie (algorithme) dans le modèle de stratégie, cependant, dans la méthode Template, seules certaines choses changent (parties de l'algorithme) et le reste des choses reste inchangé. Dans la méthode modèle, les étapes invariantes sont implémentées dans une classe de base abstraite, tandis que les étapes variantes reçoivent soit une implémentation par défaut, soit aucune implémentation du tout. Dans la méthode Template, le concepteur de composants impose les étapes requises d'un algorithme et l'ordre des étapes, mais permet au client de composant d'étendre ou de remplacer un certain nombre de ces étapes.

L'image est tirée du blog mordu .


19

Héritage versus agrégation (is-a versus has-a). C'est deux façons d'atteindre le même objectif.

Cette question montre certains arbitrages entre les choix: héritage vs agrégation


11

Les deux sont très similaires et sont tous deux consommés par le code client de manière similaire. Contrairement à ce que dit la réponse la plus populaire ci-dessus, les deux permettent la sélection d'algorithmes au moment de l'exécution .

La différence entre les deux est que tandis que le modèle de stratégie permet à différentes implémentations d'utiliser des moyens complètement différents pour atteindre le résultat souhaité, le modèle de méthode de modèle spécifie un algorithme global (la méthode du «modèle») qui est utilisé pour obtenir le résultat - - le seul choix laissé aux implémentations spécifiques (sous-classes) concerne certains détails de ladite méthode modèle. Cela se fait en demandant à la méthode template de faire des appels à une ou plusieurs méthodes abstraites qui sont surchargées (c'est-à-dire implémentées) par les sous-classes, contrairement à la méthode template qui elle-même n'est pas abstraite et non remplacée par les sous-classes .

Le code client fait un appel à la méthode de modèle en utilisant une référence / un pointeur du type de classe abstraite pointant vers une instance de l'une des sous-classes concrètes qui peuvent être déterminées au moment de l'exécution, tout comme lors de l'utilisation du modèle de stratégie.


9

Méthode de modèle:

  1. C'est basé sur l' héritage
  2. Définit le squelette de l'algorithme qui ne peut pas être modifié par les sous-classes. Seules certaines opérations peuvent être remplacées dans les sous-classes
  3. La classe parent contrôle complètement l'algorithme et ne diffère que certaines étapes des classes concrètes
  4. La liaison est effectuée au moment de la compilation

Structure Template_method :

entrez la description de l'image ici

Stratégie:

  1. Il est basé sur la délégation / composition
  2. Cela change les tripes de l'objet en modifiant le comportement de la méthode
  3. Il est utilisé pour basculer entre les familles d'algorithmes
  4. Il modifie le comportement de l'objet au moment de l'exécution en remplaçant complètement un algorithme par un autre algorithme au moment de l'exécution
  5. La liaison est effectuée au moment de l'exécution

Structure de la stratégie :

entrez la description de l'image ici

Jetez un œil à la méthode de modèle et aux articles de stratégie pour une meilleure compréhension.

Articles Similaires:

Modèle de conception de modèle dans JDK, impossible de trouver une méthode définissant un ensemble de méthodes à exécuter dans l'ordre

Exemple du monde réel du modèle de stratégie


3

Non, ils ne sont pas nécessairement consommés de la même manière. Le modèle de «méthode modèle» est un moyen de fournir des «conseils» aux futurs exécutants. Vous leur dites: «Tous les objets Personne doivent avoir un numéro de sécurité sociale» (c'est un exemple trivial mais cela fait passer l'idée correctement).

Le modèle de stratégie permet à plusieurs implémentations possibles d'être activées et désactivées. Il n'est pas (généralement) implémenté par héritage, mais plutôt en laissant l'appelant passer l'implémentation souhaitée. Un exemple pourrait être de permettre à un ShippingCalculator d'être fourni avec l'une des différentes méthodes de calcul des taxes (une implémentation NoSalesTax et peut-être une implémentation PercentageBasedSalesTax).

Ainsi, parfois, le client dira réellement à l'objet la stratégie à utiliser. Un péché

myShippingCalculator.CalculateTaxes(myCaliforniaSalesTaxImpl);

Mais le client ne ferait jamais cela pour un objet basé sur la méthode modèle. En fait, le client peut même ne pas savoir qu'un objet est basé sur la méthode modèle. Ces méthodes abstraites dans le modèle de méthode modèle pourraient même être protégées, auquel cas le client ne saurait même pas qu'elles existent.


3

Je vous suggère de lire cet article. Il explique les différences sur un exemple de cas réel.

Citation de l'article

" Comme on peut le voir, les classes d'implémentation dépendent également de la classe de méthode modèle. Cette dépendance entraîne le changement de méthode modèle si l'on veut changer certaines des étapes de l'algorithme. De l'autre côté, la stratégie encapsule complètement l'algorithme. Elle donne l'implémentation classes pour définir complètement un algorithme. Par conséquent, si un changement arrive, il faut changer le code des classes précédemment écrites. C'est la principale raison pour laquelle j'ai choisi une stratégie pour concevoir les classes.

Une caractéristique de la méthode de modèle est que la méthode de modèle contrôle l'algorithme. Ce qui peut être une bonne chose dans une autre situation, mais dans mon problème, cela me limitait à concevoir les classes. D'un autre côté, la stratégie ne contrôle pas les étapes d'un algorithme ce qui me permet d'ajouter des méthodes de conversion complètement différentes. Par conséquent, dans mon cas, la stratégie m'aide pour la mise en œuvre.

Un inconvénient de la stratégie est qu'il y a trop de redondance de code et moins de partage de code. Comme il est évident dans l'exemple présenté de cet article, je dois répéter le même code dans quatre classes encore et encore. Par conséquent, il est difficile à maintenir car si l'implémentation de notre système telle que l'étape 4 qui est commune à tous est modifiée, je devrai mettre à jour cela dans les 5 classes. De l'autre côté, dans la méthode template, je ne peux changer que la superclasse et les changements sont reflétés dans les sous-classes. Par conséquent, la méthode de modèle donne une très faible quantité de redondance et une grande quantité de partage de code entre les classes.

La stratégie permet également de changer l'algorithme au moment de l'exécution. Dans la méthode de modèle, il faudra réinitialiser l'objet. Cette caractéristique de la stratégie offre une grande flexibilité. Du point de vue de la conception, il faut préférer la composition à l'héritage. Par conséquent, l'utilisation du modèle de stratégie est également devenue le premier choix pour le développement. "


2

Le modèle de modèle est similaire au modèle de stratégie. Ces deux modèles diffèrent par leur portée et leur méthodologie.

La stratégie est utilisée pour permettre aux appelants de faire varier un algorithme entier, comme la façon de calculer différents types de taxe, tandis que la méthode modèle est utilisée pour faire varier les étapes d'un algorithme. Pour cette raison, la stratégie est plus grossière. Le modèle permet des contrôles plus fins dans la séquence des opérations, tout en permettant aux implémentations de ces détails de varier.

L'autre différence principale est que la stratégie utilise la délégation tandis que la méthode modèle utilise l'héritage. Dans Strategy, l'algorithme est délégué à une autre classe xxxStrategy à laquelle le sujet aura une référence, mais avec Template, vous sous-classez la base et remplacez les méthodes pour apporter des modifications.

depuis http://cyruscrypt.blogspot.com/2005/07/template-vs-strategy-patterns.html


2

Dans le modèle de stratégie, les sous-classes exécutent le spectacle et contrôlent l'algorithme. Ici, le code est dupliqué dans les sous-classes. La connaissance de l'algorithme et la manière de l'implémenter sont réparties sur de nombreuses classes.

Dans le modèle de modèle, la classe de base a un algorithme. Il maximise la réutilisation parmi les sous-classes. Puisque l'algorithme se trouve au même endroit, la classe de base le protège.


2

Modèle de conception de stratégie

  • Soutient la composition.
  • Vous offre la flexibilité de modifier le comportement de l'objet lors de l'exécution.
  • Moins de couplage entre le code client et le code solution / algorithme.

Modèle de modèle de conception de méthode

  • Favorise l'héritage plutôt que la composition
  • Définissez l'algorithme dans votre classe de base. Des éléments individuels d'algorithme peuvent être personnalisés dans les classes enfants.

1

Modèle de modèle:

La méthode de modèle consiste à laisser les sous-classes redéfinir certaines étapes de l'algorithme, sans changer la structure principale et les étapes de l'algorithme, définies dans la classe de base. Le modèle de modèle utilise généralement l'héritage, de sorte qu'une implémentation générique d'algorithmes peut être fournie dans la classe de base, que la sous-classe peut choisir de remplacer si nécessaire.

public abstract class RobotTemplate {
    /* This method can be overridden by a subclass if required */
    public void start() {
        System.out.println("Starting....");
    }

    /* This method can be overridden by a subclass if required */
    public void getParts() {
        System.out.println("Getting parts....");
    }

    /* This method can be overridden by a subclass if required */
    public void assemble() {
        System.out.println("Assembling....");
    }

    /* This method can be overridden by a subclass if required */
    public void test() {
        System.out.println("Testing....");
    }

    /* This method can be overridden by a subclass if required */
    public void stop() {
        System.out.println("Stopping....");
    }

    /*
     * Template algorithm method made up of multiple steps, whose structure and
     * order of steps will not be changed by subclasses.
     */
    public final void go() {
        start();
        getParts();
        assemble();
        test();
        stop();
    }
}


/* Concrete subclass overrides template step methods as required for its use */
public class CookieRobot extends RobotTemplate {
    private String name;

    public CookieRobot(String n) {
        name = n;
    }

    @Override
    public void getParts() {
        System.out.println("Getting a flour and sugar....");
    }

    @Override
    public void assemble() {
        System.out.println("Baking a cookie....");
    }

    @Override
    public void test() {
        System.out.println("Crunching a cookie....");
    }

    public String getName() {
        return name;
    }
}

Notez que dans le code ci-dessus, les étapes de l'algorithme go () seront toujours les mêmes, mais les sous-classes peuvent définir une recette différente pour effectuer une étape particulière.

Modèle de stratégie:

Le modèle de stratégie consiste à laisser le client sélectionner l'implémentation d'algorithmes concrets au moment de l'exécution. Tous les algorithmes sont isolés et indépendants, mais implémentent une interface commune, et il n'y a aucune notion de définition d'étapes particulières dans l'algorithme.

/**
 * This Strategy interface is implemented by all concrete objects representing an
 * algorithm(strategy), which lets us define a family of algorithms.
 */
public interface Logging {
    void write(String message);
}

/**
 * Concrete strategy class representing a particular algorithm.
 */
public class ConsoleLogging implements Logging {

    @Override
    public void write(String message) {
        System.out.println(message); 
    }

}

/**
 * Concrete strategy class representing a particular algorithm.
 */
public class FileLogging implements Logging {

    private final File toWrite;

    public FileLogging(final File toWrite) {
        this.toWrite = toWrite;
    }

    @Override
    public void write(String message) {
        try {
            final FileWriter fos = new FileWriter(toWrite);
            fos.write(message);
            fos.close();
        } catch (IOException e) {
            System.out.println(e);
        }
    }

}

Pour le code source complet, consultez mon référentiel github .


0

La stratégie est exposée comme une interface et une méthode de modèle comme la classe abstraite. Ceci est généralement beaucoup utilisé dans les frameworks. Par exemple, la classe MessageSource de Spring Framework est une interface de stratégie pour résoudre les messages. Le client utilise une implémentation particulière (stratégie) de cette interface.

Et l'implémentation abstraite de la même interface AbstractMessageSource, qui a une implémentation commune de résolution de messages et expose la méthode abstraite resolCode () afin que les sous-classes puissent les implémenter à leur manière. AbstractMessageSource est un exemple de méthode de modèle.

http://docs.spring.io/spring/docs/4.1.7.RELEASE/javadoc-api/org/springframework/context/support/AbstractMessageSource.html


0

Dans la méthode de modèle de ce modèle de conception, une ou plusieurs étapes d'algorithme peuvent être remplacées par des sous-classes pour permettre des comportements différents tout en s'assurant que l'algorithme global est toujours suivi (Wiki).

La méthode de modèle de nom de modèle signifie ce qu'elle est. Disons que nous avons une méthode CalculateSomething () et que nous voulons modéliser cette méthode. Cette méthode sera déclarée dans la classe de base une méthode non virtuelle. Dites que la méthode ressemble à ceci.

CalculateSomething(){
    int i = 0;
    i = Step1(i);
    i++;
    if (i> 10) i = 5;
    i = Step2(i);
    return i;

} L'implémentation des méthodes Step1 et Step2 peut être donnée par des classes dérivées.

Dans Strategy Pattern, il n'y a pas d'implémentation fournie par la base (c'est la raison pour laquelle la base est vraiment une interface dans le diagramme de classes)

L'exemple classique est le tri. En fonction du nombre d'objets à trier, la classe d'algorithme appropriée (fusion, bulle, rapide, etc.) est créée et l'ensemble de l'algorithme est encapsulé dans chaque classe.

Pouvons-nous maintenant implémenter le tri comme méthode de modèle? Vous pouvez certainement, mais vous ne trouverez pas beaucoup / aucun point commun à extraire et à placer dans l'implémentation de base. Donc, cela va à l'encontre de l'objectif du modèle de méthode de modèle.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.