web-dev-qa-db-fra.com

Polymorphisme vs modèle de stratégie

Quelle est la différence entre le modèle Strategy et Polymorphism en Java?

Je suis confus que tout ce qui est réalisé via Strategy Pattern est fondamentalement possible par polymorphisme. Corrigez-moi si je me trompe à cet égard.

Veuillez également me fournir un exemple pour éliminer ma confusion.

47
TryinHard

Pour moi, le lien de CKing post et l'exemple dans Wikipedia sont assez clairs, mais je vais essayer de vous donner un nouvel exemple. Comme ils l'ont dit, le modèle de stratégie est principalement un moyen de modifier le comportement d'un algorithme lors de l'exécution . Bien sûr, vous pouvez y parvenir de différentes manières (telles que maintenir une valeur et utiliser un commutateur, mais ce ne serait pas aussi agréable que le modèle de stratégie).

Imaginons que vous développiez un jeu de stratégie au tour par tour avec deux types d'unités : Infanterie et Réservoir (sous-classes d'unité). Votre terrain peut être Plaines , Chemin de fer ou Forêts .

class Unit{
    MovementStrategy ms;      
    final int baseMovement;
    int x,y;

    public Unit(int baseMovement){
        this.baseMovement = baseMovement;
    }

    abstract void fire();

    void moveForward(){
        x = x + ms.getHexagonsToMove(baseMovement);
    }

    void setMovementStrategy(MovementStrategy ms){
        this.ms = ms;
    }
}

Toute sous-classe d'unité doit implémenter la méthode fire () car ça va être complètement différent pour eux (Les tirs de chars sont lourds et longs -distance ronde et l'infanterie a tiré plusieurs balles lumineuses à courte distance). Dans cet exemple, nous utilisons un polymorphisme/héritage normal puisque la méthode fire () sera vraiment différente pour n'importe quelle unité, et elle ne changera pas pendant le jeu .

class Infantry extends Unit{
    public Infantry(){
        super(2);
    }

    void fire(){
        //whatever
    }
}

class Tank extends Unit{
    public Tank(){
        super(5);
    }

    void fire(){
        //whatever
    }
}

Les unités sont également capables de se déplacer et ont un champ baseMovement qui contient le nombre d'hexagones qu'elle peut parcourir. Nous développons un jeu de stratégie, pas une simulation du monde réel, donc peu nous importe comment ils se déplacent, nous voulons simplement ajouter une valeur à leurs coordonnées (dans mon exemple, j'utilise uniquement les coordonnées X afin d'obtenir un code plus simple ). Si tout le terrain était le même, nous n'aurions pas besoin d'objet Strategy ... mais nous devons changer le comportement de la méthode move () lors de l'exécution!

Donc, nous implémentons une classe différente MovementStrategy pour chacun de nos types de Terrain, et nous programmons notre jeu pour déclencher une setMovementStrategy () à n'importe quelle unité qui se déplace sur chaque hexagone. Et nous n'avons même pas besoin d'écrire autre chose dans nos sous-classes d'unités.

interface MovementStrategy{
    public int getHexagonsToMove(int base);
}

class PlainMovementStrategy implements MovementStrategy{
    public int getHexagonsToMove(int base){
        return base;
    }
}

class RailroadMovementStrategy implements MovementStrategy{
    public int getHexagonsToMove(int base){
        return base*3;
    }
}

class ForestMovementStrategy implements MovementStrategy{
    public int getHexagonsToMove(int base){
        return (int)(base/2);
    }
}   

Maintenant, quand une unité se déplace à l'intérieur d'une forêt , nous appelons

unit.setMovementStrategy(new ForestMovementStrategy());

Et dès qu'il passe à un Plain , nous faisons:

unit.setMovementStrategy(new PlainMovementStrategy());

Maintenant, nous pouvons changer la distance à laquelle nos unités se déplacent en fonction du terrain, et nous n'avons pas besoin de réécrire dans aucune des sous-classes.

J'espère que cela vous aidera à mieux comprendre la différence.

43
rolgalan

Je suis confus que tout ce qui est réalisé via Strategy Pattern est fondamentalement possible par polymorphisme.

Vous ne pouvez pas conduire une voiture sans volant. Cela ne signifie pas qu'un volant est une voiture. De même, le modèle de stratégie repose sur le polymorphisme, mais cela ne signifie pas qu'ils sont la même chose.

Le modèle de stratégie a pour but de promouvoir l'utilisation de la composition (has-a) par rapport à l'héritage (is-a). Au lieu que votre classe hérite du comportement d'une super classe, vous définissez le comportement dans une classe distincte et votre classe en a une référence.

En ce qui concerne un exemple, jetez un œil à la réponse this qui fait du bon travail.

26
CKing

Polymorphisme vs modèle de stratégie avec noyau Java exemples

  • Différence de base: Le polymorphisme est un concept de langage de programmation et Le modèle de stratégie en est un de modèle de conception comportementale du GoF .

  • Le polymorphisme est la fourniture d'une interface unique à des entités de différents types.
    Exemple: Le volant (c'est-à-dire l'interface) est le même quel que soit le type de mécanisme de direction utilisé. Autrement dit, le volant fonctionne de la même manière, que votre voiture soit dotée d'une direction manuelle, d'une direction assistée ou d'une direction à crémaillère. Par conséquent, une fois que vous savez utiliser le volant, vous pouvez conduire n'importe quel type de voiture.

  • En programmation, Polymorphisme implémenté de deux manières:

    • Polymorphisme à liaison précoce/statique/à la compilation (ex: surcharge de fonctions)
    • Polymorphisme à liaison tardive/dynamique/à l'exécution (ex: remplacement de fonction)

Temps de compilation: la période pendant laquelle vous, le développeur, compilez votre code.
Exécution: la période pendant laquelle un utilisateur exécute votre logiciel.
Source

  • A modèle de stratégie définit un ensemble d'algorithmes qui peuvent être utilisés de manière interchangeable.

    • Le modèle de stratégie est un modèle dynamique (comment voulez-vous exécuter un comportement dans le logiciel?).
    • Exemple de noyau Java: Java.util.Comparator#compare(), exécuté par entre autres Collections#sort().

    • Les modes de transport sont analogues au modèle de conception de la stratégie . Nous utilisons la voiture, le vélo, le bus, le train local et ainsi de suite .. différentes stratégies pour aller au bureau jour après jour.

10
Premraj

Si vous établissez une analogie où:

  • dans un cas, vous disposez de plusieurs méthodes remplaçables;
  • dans l'autre cas vous avez une interface Strategy avec plusieurs implémentations,

alors la différence est le degré de couplage, qui est très fort dans le premier cas, alors que dans le second cas tout code étranger peut participer à la logique de votre classe en contribuant à l'implémentation de sa stratégie.

7
Marko Topolnik

Q: Quelle est la différence entre le modèle de stratégie et le polymorphisme en Java?

La question est certainement déroutante car au départ il ne semble pas y avoir de relation entre ces deux idées.

Le polymorphisme est un concept beaucoup plus large en programmation et oui, le modèle de stratégie de Java utilise une forme de polymorphisme cataloguée polymorphisme d'inclusion pour accomplir son intention, mais ce n'est en aucun cas signifie le seul type de polymorphisme qui existe, ce n'est pas non plus le seul moyen de mettre en œuvre le modèle de stratégie comme je le démontrerai bientôt.

Le polymorphisme n'est pas quelque chose qui n'existe que dans Java ou dans les langages de programmation orientés objet. Différentes formes de polymorphisme existent dans tous les paradigmes de programmation et pas dans tous les langages vous êtes obligé d'utiliser le polymorphisme pour implémenter un modèle de stratégie (par exemple les langages fonctionnels).

Pour plus de discussion sur ce sujet, veuillez lire cette autre réponse où nous avons discuté si le polymorphisme est possible sans héritage et je fournis des références et des exemples intéressants à d'autres types de polymorphisme comme le polymorphisme paramétrique et ad hoc.

Idéalement, cela vous révélera que le polymorphisme est un concept plus vaste qui va au-delà des limites de la programmation orientée objet et même au-delà de l'héritage et du sous-typage.

Q: Je suis confus que tout ce qui est réalisé via Strategy Pattern est fondamentalement possible par polymorphisme. Corrigez-moi si je me trompe à cet égard.

De mon point de vue, les relations entre ces deux concepts sont les suivantes: que le modèle de stratégie exploite la puissance du polymorphisme disponible dans des langages comme Java pour mettre en œuvre son intention, et que le polymorphisme peut être considéré en soi comme un modèle.

Par exemple, considérez cette citation du livre du GoF:

Si nous supposions des langages procéduraux, nous aurions pu inclure des modèles de conception appelés "héritage", "encapsulation" et "polymorphisme".

C'est juste que nous considérons rarement le polymorphisme comme un modèle, d'abord parce qu'il implique beaucoup de choses et parce qu'il est implémenté différemment dans différentes langues et aussi parce qu'il se présente généralement comme une forme de fonctionnalité de langage.

Dans son livre Elemental Design Patterns, Jason Mc C. Smith commente la citation du GoF ci-dessus en disant:

Les modèles sont des concepts indépendants du langage; ils prennent forme et deviennent des solutions concrètes lorsque vous les implémentez dans un langage particulier avec un ensemble donné de fonctionnalités et de constructions de langage [...] Cela signifie qu'il est un peu étrange de parler de "modèle de conception Java", "modèles de conception C++". "," Websphere design pattern "et ainsi de suite, même si nous le faisons tous. C'est une forme de raccourci légèrement paresseux pour ce que nous voulons vraiment dire, ou devrions signifier: les modèles de conception mis en œuvre dans Java, C++, WebSphere et ainsi de suite, indépendamment du langage ou de l'API.

Donc, comme vous pouvez le voir, vous pensez dans le modèle de stratégie du point de vue de la mise en œuvre Java, mais dans d'autres paradigmes de langage, ce modèle peut avoir été mis en œuvre de différentes manières, probablement sans utiliser l'héritage du tout, par exemple, dans les langages de programmation fonctionnels purs, cela est très certainement implémenté en utilisant fonctions d'ordre élevé et composition de fonction .

En tant que tel, ce serait une implémentation de modèle de stratégie sans recourir à polymorphisme d'inclusion du tout. Dans une stratégie de composition de fonctions, nous pouvons encore utiliser d'autres formes de polymorphisme (par exemple paramétrique), mais ce n'est pas une exigence pour le modèle de stratégie

Q: Veuillez également me donner un exemple pour éliminer ma confusion.

Comme indiqué ci-dessus, dans Java nous sommes probablement obligés d'utiliser le polymorphisme d'inclusion pour implémenter un modèle de stratégie, mais comme expliqué ci-dessus également, les modèles ne sont pas quelque chose qui appartient à un langage spécifique, donc si nous Si vous considérez le modèle de stratégie comme un concept vivant en dehors des frontières linguistiques, vous verrez facilement d'autres langues le mettre en œuvre de différentes manières.

Dans un langage fonctionnel hypothétique, je peux avoir une fonction qui lit certaines données d'un fichier, peut-être que le fichier est crypté et que vous devez fournir une stratégie de décryptage:

function readFile(path: String, decrypt: string -> string) {
    return decrypt(loadFromDisk(path));
}

Et cet argument decrypt est une fonction qui sert le but d'un modèle de stratégie, il encapsule un algorithme interchangeable.

Maintenant vous pouvez faire

readFile("customers.txt", aes)
readFile("finance.txt", blowfish)

aes et blowfish sont des stratégies de fonction de déchiffrement.

Il existe des dizaines de langues qui fonctionnent comme ceci, SML, Haskell, JavaScript, etc.

7
Edwin Dalorzo

Tout d'abord. Le polymorphisme peut signifier deux choses différentes. Le plus souvent, le polymorphisme fait référence à un type polymorphe. Cependant, vous demandez le modèle.

Le code polymorphe peut se changer à chaque fois qu'il s'exécute alors que la fonction du code reste la même. Un exemple simple est de faire 1 + 3 = 4 au lieu de 5-1 = 4. Les deux obtiennent le même résultat en utilisant un code différent. Ceci est utile pour le code qui ne veut pas être reconnu, c'est-à-dire les virus informatiques ou le code cryptographique.

D'autre part, le modèle de stratégie utilise une famille d'algorithmes qui peuvent être échangés. Cela peut être utilisé lors de la traduction de texte. Tout d'abord, un code détermine la langue. si la langue est le suédois ou l'espagnol, le texte sera traité par différentes fonctions de la même famille, translateSwedish () ou translateSpanish ().

Pour arrondir les choses. Le code polymorphe utilise un code différent qui permet d'obtenir le même résultat. Alors que la stratégie utilise un code différent pour obtenir de meilleurs résultats.

3
Herman Wilén

Considère ceci

nous avons des animaux et un objet de modèle de stratégie pour décrire comment ils se déplacent ... par exemple

voler/nager/marcher

Étant donné le grand nombre d'animaux qui utilisent l'une de ces méthodes (c'est-à-dire des milliers d'animaux différents qui volent), nous devons utiliser le même code pour de nombreux animaux différents. Ce code ne devrait exister qu'en un seul endroit, afin qu'il soit facilement modifié et n'occupe aucun espace inutile.

Dans cet exemple, une approche simple du polymorphisme entraînera une duplication massive de code. Une approche plus complexe qui place une classe intermédiaire entre l'animal et disons que le rouge-gorge ne tient pas compte du fait que la façon dont un animal se déplace n'est pas vraiment ce qui le définit. De plus, il est possible qu'un animal ait d'autres objets de stratégie et ils ne peuvent pas tous être rendus polymorphes à travers des classes intermédiaires.

2
Joshua Byer

Le polymorphisme est un principe et la stratégie est un modèle de conception

De la documentation Oracle page

La définition du dictionnaire du polymorphisme fait référence à un principe de la biologie dans lequel un organisme ou une espèce peut avoir de nombreuses formes ou stades différents. Ce principe peut également être appliqué à la programmation orientée objet et aux langages comme le langage Java. Les sous-classes d'une classe peuvent définir leurs propres comportements uniques tout en partageant certaines des mêmes fonctionnalités de la classe parente.

Le polymorphisme peut être obtenu en temps de compilation (surcharge de méthode) et en temps d'exécution (remplacement de méthode).

Strategy_pattern

  1. Définit une famille d'algorithmes,
  2. Encapsule chaque algorithme, et
  3. Rend les algorithmes interchangeables au sein de cette famille.

La stratégie peut utiliser le principe de polymorphisme d'exécution pour obtenir la fonctionnalité souhaitée.

Le modèle de stratégie avait un autre composant appelé Contexte dans son diagramme d'URL. Reportez-vous aux messages SE ci-dessous:

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

Est-ce que Java a une classe de contexte redondante?

Quelques articles plus utiles:

stratégie par sourcemaking

2
Ravindra babu

Une définition du polymorphisme est la fourniture d'une interface unique à des entités de différents types.

Dans cet esprit, disons que vous avez une interface "oiseau" et que toutes vos classes d'oiseaux doivent implémenter la méthode "laysEggs ()", enfin pas de biggie qui fonctionne. Et pendant que vous continuez à coder votre "programme paradisiaque", vous ajoutez maintenant le "fly ()" et réalisez que surcharger et remplacer les pingouins et les kiwis est inutile car dans la vraie vie, ils ne peuvent pas voler, mais vous devez toujours mettre en œuvre cette méthode. Cela peut devenir fastidieux et inutile car vous êtes confronté à l'autruche et à d'autres qui ne peuvent pas voler. Et pire encore lors de l'ajout de la méthode "swim ()" car encore moins d'oiseaux peuvent nager. Comme vous le savez peut-être déjà, le modèle de stratégie résout ce problème.

En termes de boiteux, vous pouvez considérer le polymorphisme comme un conglomérat de pratiques, tandis que le modèle de stratégie est la meilleure pratique pour un cas spécifique. Exemple: le modèle de stratégie doit être utilisé lorsque le comportement d'un algorithme doit être sélectionné lors de l'exécution (via des algorithmes interchangeables). Et bien qu'il soit en quelque sorte vrai que tout ce qui est réalisé via le modèle de stratégie est fondamentalement possible par polymorphisme, sans connaissance du modèle de stratégie, cela vous laisserait avec le problème de "réinventer la roue" pour résoudre ce problème spécifique. En conclusion, ils sont très différents même si l'un est basé sur l'autre. Je vous laisse voir le code "Ender Muab'Dib" car il est bien expliqué si vous voulez toujours un exemple de code de ma part, demandez, applaudissez et j'espère que j'ai aidé.

2
Omar Ayala