63 votes

Comment fonctionne le modèle de stratégie ?

Comment fonctionne-t-il, à quoi sert-il et quand doit-on l'utiliser ?

78voto

e-satis Points 146299

Expliquons le schéma stratégique de manière simple :

Vous avez une classe Car() avec une méthode run() Vous l'utilisez donc de cette façon dans un pseudo-langage :

mycar = new Car()
mycar.run()

Maintenant, vous voulez peut-être changer le run() à la volée, pendant que le programme s'exécute. Par exemple, vous pourriez vouloir simuler une panne de moteur ou l'utilisation d'un bouton "boost" dans un jeu vidéo.

Il existe plusieurs façons de réaliser cette simulation : l'utilisation d'instructions conditionnelles et d'une variable drapeau en est une. Le modèle de stratégie en est une autre : il délègue le comportement de l'élément run() à une autre classe :

Class Car()
{
    this.motor = new Motor(this) 

    // passing "this" is important for the motor so it knows what it is running

    method run()
    {
        this.motor.run()
    }

    method changeMotor(motor)
    {
        this.motor = motor 
    }

}

Si vous voulez changer le comportement de la voiture, vous pouvez simplement changer le moteur. (Plus facile dans un programme que dans la vie réelle, n'est-ce pas ? ;-) )

C'est très utile si vous avez beaucoup d'états complexes : vous pouvez les modifier et les maintenir beaucoup plus facilement.

38voto

Jorge Córdoba Points 18919

Problème

Le modèle de stratégie est utilisé pour résoudre des problèmes qui pourraient (ou dont on prévoit qu'ils pourraient) être mis en œuvre ou résolus par différentes stratégies et qui possèdent une interface clairement définie pour de tels cas. Chaque stratégie est parfaitement valable en soi, certaines d'entre elles étant préférables dans certaines situations qui permettent à l'application de passer de l'une à l'autre pendant l'exécution.

Exemple de code

namespace StrategyPatterns
{
  // Interface definition for a Sort algorithm
  public interface ISort
  {
    void Sort(List<string> list)
  }

  // QuickSort implementation
  public class CQuickSorter : ISort
  {
    void Sort(List<string> list)
    {
      // Here will be the actual implementation
    }
  }

  // BubbleSort implementation
  public class CBubbleSort : ISort
  {
    void Sort(List<string> list)
    {
      // The actual implementation of the sort
    }
  }

  // MergeSort implementation
  public class CMergeSort : ISort
  {
    void Sort(List<string> list)
    {
      // Again the real implementation comes here
    }
  }

  public class Context
  {
    private ISort sorter;

    public Context(ISort sorter)
    {
      // We pass to the context the strategy to use
      this.sorter = sorter;
    }

    public ISort Sorter
    {
      get{return sorter;)
    }
  }

  public class MainClass
  {
    static void Main()
    {
       List<string> myList = new List<string>();

       myList.Add("Hello world");
       myList.Add("Another item");
       myList.Add("Item item");

       Context cn = new Context(new CQuickSorter());
       // Sort using the QuickSort strategy
       cn.Sorter.Sort(myList);
       myList.Add("This one goes for the mergesort");
       cn = new Context(new CMergeSort());
       // Sort using the merge sort strategy
       cn.Sorter.Sort(myList);
    }
  }
}

21voto

Malf Points 93
  • Qu'est-ce qu'une stratégie ? Une stratégie est un plan d'action conçu pour atteindre un objectif spécifique ;
  • "Définir une famille d'algorithmes, encapsuler chacun d'entre eux et les rendre interchangeables. La stratégie permet à l'algorithme de varier indépendamment des clients qui l'utilisent." (Gang of Four) ;
  • Spécifie un ensemble de classes, chacune représentant un comportement potentiel. Le passage d'une classe à l'autre modifie le comportement de l'application. (la stratégie) ;
  • Ce comportement peut être sélectionné au moment de l'exécution (à l'aide du polymorphisme) ou de la conception ;
  • Capturez l'abstraction dans une interface, enterrez les détails de mise en œuvre dans les classes dérivées ;

enter image description here

  • Une alternative à la stratégie consiste à modifier le comportement de l'application en utilisant une logique conditionnelle. (MAUVAIS) ;

  • L'utilisation de ce modèle facilite l'ajout ou la suppression de comportements spécifiques, sans avoir à recoder et à tester à nouveau tout ou partie de l'application ;

  • Bons usages :

    • Lorsque l'on dispose d'un ensemble d'algorithmes similaires et que l'on doit passer de l'un à l'autre dans différentes parties de l'application. Avec le Strategy Pattern, il est possible d'éviter les "si" et de faciliter la maintenance ;
    • Lorsque nous voulons ajouter de nouvelles méthodes à la superclasse qui n'ont pas nécessairement de sens pour chaque sous-classe. Au lieu d'utiliser une interface de manière traditionnelle, en ajoutant la nouvelle méthode, nous utilisons une variable d'instance qui est une sous-classe de la nouvelle interface Functionality. C'est ce qu'on appelle la composition : au lieu d'hériter d'une capacité par le biais de l'héritage, la classe est composée d'objets possédant la bonne capacité ;

6voto

Bill the Lizard Points 147311

Directement de la Article de Wikipédia sur les modèles de stratégie :

Le modèle de stratégie est utile dans les situations où il est nécessaire de permuter dynamiquement les algorithmes utilisés dans une application. Le patron de stratégie est destiné à fournir un moyen de définir une famille d'algorithmes, d'encapsuler chacun d'eux dans un objet et de les rendre interchangeables. Le patron de stratégie permet aux algorithmes de varier indépendamment des clients qui les utilisent.

6voto

Andrew Swan Points 5118

Un modèle étroitement lié est le modèle délégué ; dans les deux cas, une partie du travail est transmise à un autre composant. Si je comprends bien, la différence entre ces modèles est la suivante (et corrigez-moi si je me trompe) :

  • Dans le Délégué le délégué est instancié par la classe englobante (délégant) ; ceci permet la réutilisation du code par composition plutôt que par héritage. La classe englobante peut connaître le type concret du délégué, par exemple si elle invoque elle-même son constructeur (par opposition à l'utilisation d'une fabrique).

  • Dans le Stratégie le composant qui exécute la stratégie est une dépendance fournie au composant englobant (utilisant) via son constructeur ou un setter (selon votre religion). Le composant utilisateur ne sait absolument pas quelle stratégie est utilisée ; la stratégie est toujours invoquée via une interface.

Quelqu'un connaît-il d'autres différences ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X